738 lines
34 KiB
HTML
738 lines
34 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Patient Consents - 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 active">Patient Consents</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Patient Consents
|
|
<small>Manage signed consent forms and signatures</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN row -->
|
|
<div class="row">
|
|
<div class="col-xl-12">
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Patient Consent Management</h4>
|
|
<div class="panel-heading-btn">
|
|
<button type="button" class="btn btn-primary btn-sm me-2" data-bs-toggle="modal" data-bs-target="#requestConsentModal">
|
|
<i class="fa fa-plus me-2"></i>Request Consent
|
|
</button>
|
|
<button type="button" class="btn btn-info btn-sm me-2" onclick="exportConsents()">
|
|
<i class="fa fa-download me-2"></i>Export
|
|
</button>
|
|
<button type="button" class="btn btn-secondary btn-sm me-2" onclick="bulkActions()">
|
|
<i class="fa fa-tasks me-2"></i>Bulk Actions
|
|
</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">
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-3">
|
|
<div class="card border-primary">
|
|
<div class="card-body text-center">
|
|
<div class="fs-24px fw-bold text-primary">{{ total_consents }}</div>
|
|
<div class="small text-muted">Total Consents</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card border-success">
|
|
<div class="card-body text-center">
|
|
<div class="fs-24px fw-bold text-success">{{ signed_consents }}</div>
|
|
<div class="small text-muted">Signed</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card border-warning">
|
|
<div class="card-body text-center">
|
|
<div class="fs-24px fw-bold text-warning">{{ pending_consents }}</div>
|
|
<div class="small text-muted">Pending</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="card border-danger">
|
|
<div class="card-body text-center">
|
|
<div class="fs-24px fw-bold text-danger">{{ expired_consents }}</div>
|
|
<div class="small text-muted">Expired</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters and Search -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-3">
|
|
<div class="form-floating">
|
|
<input type="text" class="form-control" id="search-input" placeholder="Search consents...">
|
|
<label for="search-input">Search consents...</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-floating">
|
|
<select class="form-select" id="status-filter">
|
|
<option value="">All Status</option>
|
|
<option value="PENDING">Pending</option>
|
|
<option value="SIGNED">Signed</option>
|
|
<option value="EXPIRED">Expired</option>
|
|
<option value="REVOKED">Revoked</option>
|
|
<option value="DECLINED">Declined</option>
|
|
</select>
|
|
<label for="status-filter">Status</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-floating">
|
|
<select class="form-select" id="form-filter">
|
|
<option value="">All Forms</option>
|
|
{% for form in consent_forms %}
|
|
<option value="{{ form.pk }}">{{ form.title }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="form-filter">Form Type</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-floating">
|
|
<input type="date" class="form-control" id="date-filter">
|
|
<label for="date-filter">Date</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="btn-group w-100">
|
|
<button type="button" class="btn btn-outline-secondary" onclick="clearFilters()">
|
|
<i class="fa fa-times me-2"></i>Clear
|
|
</button>
|
|
<button type="button" class="btn btn-outline-primary" onclick="applyFilters()">
|
|
<i class="fa fa-search me-2"></i>Filter
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="refreshData()">
|
|
<i class="fa fa-refresh"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bulk Actions Bar -->
|
|
<div id="bulk-actions-bar" class="alert alert-info d-none">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<span id="selected-count">0</span> consent(s) selected
|
|
</div>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-success" onclick="bulkApprove()">
|
|
<i class="fa fa-check me-2"></i>Approve
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-warning" onclick="bulkRemind()">
|
|
<i class="fa fa-bell me-2"></i>Send Reminder
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-info" onclick="bulkExport()">
|
|
<i class="fa fa-download me-2"></i>Export
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-danger" onclick="bulkRevoke()">
|
|
<i class="fa fa-times me-2"></i>Revoke
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Consents Table -->
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-hover" id="consents-table">
|
|
<thead class="table-dark">
|
|
<tr>
|
|
<th width="40">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="select-all">
|
|
</div>
|
|
</th>
|
|
<th>Patient</th>
|
|
<th>Consent Form</th>
|
|
<th>Status</th>
|
|
<th>Requested</th>
|
|
<th>Signed</th>
|
|
<th>Expires</th>
|
|
<th>Signed By</th>
|
|
<th width="120">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for consent in object_list %}
|
|
<tr data-consent-id="{{ consent.pk }}">
|
|
<td>
|
|
<div class="form-check">
|
|
<input class="form-check-input consent-checkbox" type="checkbox" value="{{ consent.pk }}">
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<div class="me-3">
|
|
<div class="w-40px h-40px bg-primary rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="fa fa-user text-white"></i>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="fw-bold">
|
|
<a href="{% url 'patients:patient_detail' consent.patient.pk %}" class="text-decoration-none">
|
|
{{ consent.patient.get_full_name }}
|
|
</a>
|
|
</div>
|
|
<div class="small text-muted">{{ consent.patient.patient_id }}</div>
|
|
<div class="small text-muted">{{ consent.patient.date_of_birth|date:"M d, Y" }}</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<div class="fw-bold">
|
|
<a href="{% url 'patients:consent_form_detail' consent.consent_form.pk %}" class="text-decoration-none">
|
|
{{ consent.consent_form.title }}
|
|
</a>
|
|
</div>
|
|
<div class="small text-muted">{{ consent.consent_form.get_category_display }}</div>
|
|
{% if consent.consent_form.is_required %}
|
|
<span class="badge bg-danger mt-1">Required</span>
|
|
{% endif %}
|
|
<span class="badge bg-light text-dark mt-1">v{{ consent.consent_form.version }}</span>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-{% if consent.status == 'SIGNED' %}success{% elif consent.status == 'PENDING' %}warning{% elif consent.status == 'EXPIRED' %}danger{% elif consent.status == 'REVOKED' %}secondary{% else %}info{% endif %}">
|
|
{{ consent.get_status_display }}
|
|
</span>
|
|
{% if consent.is_urgent %}
|
|
<br><span class="badge bg-danger mt-1">Urgent</span>
|
|
{% endif %}
|
|
{% if consent.is_expiring_soon %}
|
|
<br><span class="badge bg-warning mt-1">Expiring Soon</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="small">
|
|
<div>{{ consent.requested_at|date:"M d, Y" }}</div>
|
|
<div class="text-muted">{{ consent.requested_at|time:"H:i" }}</div>
|
|
<div class="text-muted">by {{ consent.requested_by.get_full_name|default:"System" }}</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
{% if consent.signed_at %}
|
|
<div class="small">
|
|
<div>{{ consent.signed_at|date:"M d, Y" }}</div>
|
|
<div class="text-muted">{{ consent.signed_at|time:"H:i" }}</div>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">Not signed</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if consent.expires_at %}
|
|
<div class="small">
|
|
<div>{{ consent.expires_at|date:"M d, Y" }}</div>
|
|
{% if consent.is_expired %}
|
|
<div class="text-danger">Expired</div>
|
|
{% elif consent.is_expiring_soon %}
|
|
<div class="text-warning">Expiring Soon</div>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">No expiration</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if consent.signed_by %}
|
|
<div class="small">
|
|
<div class="fw-bold">{{ consent.signed_by.get_full_name }}</div>
|
|
<div class="text-muted">{{ consent.signed_by.relationship|default:"Patient" }}</div>
|
|
{% if consent.witness %}
|
|
<div class="text-muted">Witness: {{ consent.witness.get_full_name }}</div>
|
|
{% endif %}
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">Not signed</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<a href="{% url 'patients:patient_consent_detail' consent.pk %}" class="btn btn-outline-primary btn-sm" title="View Details">
|
|
<i class="fa fa-eye"></i>
|
|
</a>
|
|
{% if consent.status == 'PENDING' %}
|
|
<button type="button" class="btn btn-outline-success btn-sm" onclick="signConsent('{{ consent.pk }}')" title="Sign">
|
|
<i class="fa fa-signature"></i>
|
|
</button>
|
|
{% endif %}
|
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="viewDocument('{{ consent.pk }}')" title="View Document">
|
|
<i class="fa fa-file-pdf"></i>
|
|
</button>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fa fa-cog"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
{% if consent.status == 'PENDING' %}
|
|
<li><a class="dropdown-item" href="#" onclick="sendReminder('{{ consent.pk }}')">
|
|
<i class="fa fa-bell me-2"></i>Send Reminder
|
|
</a></li>
|
|
{% endif %}
|
|
{% if consent.status == 'SIGNED' and consent.expires_at %}
|
|
<li><a class="dropdown-item" href="#" onclick="renewConsent('{{ consent.pk }}')">
|
|
<i class="fa fa-refresh me-2"></i>Renew
|
|
</a></li>
|
|
{% endif %}
|
|
<li><a class="dropdown-item" href="#" onclick="downloadConsent('{{ consent.pk }}')">
|
|
<i class="fa fa-download me-2"></i>Download
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="printConsent('{{ consent.pk }}')">
|
|
<i class="fa fa-print me-2"></i>Print
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
{% if consent.status in 'PENDING,SIGNED' %}
|
|
<li><a class="dropdown-item text-warning" href="#" onclick="revokeConsent('{{ consent.pk }}')">
|
|
<i class="fa fa-times me-2"></i>Revoke
|
|
</a></li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="9" class="text-center py-4">
|
|
<div class="text-muted">
|
|
<i class="fa fa-file-signature fa-3x mb-3"></i>
|
|
<h5>No patient consents found</h5>
|
|
<p>Request your first patient consent to get started.</p>
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#requestConsentModal">
|
|
<i class="fa fa-plus me-2"></i>Request Consent
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if is_paginated %}
|
|
<div class="d-flex justify-content-between align-items-center mt-3">
|
|
<div class="text-muted">
|
|
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }} consents
|
|
</div>
|
|
<nav>
|
|
<ul class="pagination pagination-sm mb-0">
|
|
{% if page_obj.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page=1">« First</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in page_obj.paginator.page_range %}
|
|
{% if page_obj.number == num %}
|
|
<li class="page-item active">
|
|
<span class="page-link">{{ num }}</span>
|
|
</li>
|
|
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if page_obj.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
|
|
</li>
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last »</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
</div>
|
|
</div>
|
|
<!-- END row -->
|
|
|
|
<!-- Request Consent Modal -->
|
|
<div class="modal fade" id="requestConsentModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Request Patient Consent</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="request-consent-form">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
<select class="form-select" id="patient-select" required>
|
|
<option value="">Select patient...</option>
|
|
{% for patient in patients %}
|
|
<option value="{{ patient.pk }}">{{ patient.get_full_name }} ({{ patient.patient_id }})</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="patient-select">Patient</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
<select class="form-select" id="consent-form-select" required>
|
|
<option value="">Select consent form...</option>
|
|
{% for form in consent_forms %}
|
|
<option value="{{ form.pk }}">{{ form.title }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<label for="consent-form-select">Consent Form</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="consent-notes" class="form-label">Notes</label>
|
|
<textarea class="form-control" id="consent-notes" rows="3"></textarea>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="urgent-consent">
|
|
<label class="form-check-label" for="urgent-consent">
|
|
Mark as urgent
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="send-notification" checked>
|
|
<label class="form-check-label" for="send-notification">
|
|
Send notification to patient
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="button" class="btn btn-primary" onclick="requestConsent()">
|
|
<i class="fa fa-paper-plane me-2"></i>Request Consent
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize tooltips
|
|
$('[title]').tooltip();
|
|
|
|
// Auto-refresh every 30 seconds
|
|
setInterval(function() {
|
|
if (!$('.modal').hasClass('show')) {
|
|
refreshData();
|
|
}
|
|
}, 30000);
|
|
|
|
// Search functionality
|
|
$('#search-input').on('input', function() {
|
|
filterTable();
|
|
});
|
|
|
|
// Filter functionality
|
|
$('#status-filter, #form-filter, #date-filter').on('change', function() {
|
|
filterTable();
|
|
});
|
|
|
|
// Select all checkbox
|
|
$('#select-all').on('change', function() {
|
|
$('.consent-checkbox').prop('checked', $(this).is(':checked'));
|
|
updateBulkActions();
|
|
});
|
|
|
|
// Individual checkboxes
|
|
$(document).on('change', '.consent-checkbox', function() {
|
|
updateBulkActions();
|
|
|
|
// Update select all checkbox
|
|
var totalCheckboxes = $('.consent-checkbox').length;
|
|
var checkedCheckboxes = $('.consent-checkbox:checked').length;
|
|
$('#select-all').prop('checked', totalCheckboxes === checkedCheckboxes);
|
|
});
|
|
});
|
|
|
|
function filterTable() {
|
|
var searchTerm = $('#search-input').val().toLowerCase();
|
|
var statusFilter = $('#status-filter').val();
|
|
var formFilter = $('#form-filter').val();
|
|
var dateFilter = $('#date-filter').val();
|
|
|
|
$('#consents-table tbody tr').each(function() {
|
|
var row = $(this);
|
|
var text = row.text().toLowerCase();
|
|
var status = row.find('.badge').first().text().trim();
|
|
|
|
var showRow = true;
|
|
|
|
// Search filter
|
|
if (searchTerm && !text.includes(searchTerm)) {
|
|
showRow = false;
|
|
}
|
|
|
|
// Status filter
|
|
if (statusFilter && !status.toLowerCase().includes(statusFilter.toLowerCase())) {
|
|
showRow = false;
|
|
}
|
|
|
|
// Additional filters would be implemented here
|
|
|
|
row.toggle(showRow);
|
|
});
|
|
}
|
|
|
|
function clearFilters() {
|
|
$('#search-input').val('');
|
|
$('#status-filter').val('');
|
|
$('#form-filter').val('');
|
|
$('#date-filter').val('');
|
|
filterTable();
|
|
}
|
|
|
|
function applyFilters() {
|
|
filterTable();
|
|
toastr.info('Filters applied');
|
|
}
|
|
|
|
function refreshData() {
|
|
location.reload();
|
|
}
|
|
|
|
function updateBulkActions() {
|
|
var selectedCount = $('.consent-checkbox:checked').length;
|
|
$('#selected-count').text(selectedCount);
|
|
|
|
if (selectedCount > 0) {
|
|
$('#bulk-actions-bar').removeClass('d-none');
|
|
} else {
|
|
$('#bulk-actions-bar').addClass('d-none');
|
|
}
|
|
}
|
|
|
|
function requestConsent() {
|
|
var formData = {
|
|
patient: $('#patient-select').val(),
|
|
consent_form: $('#consent-form-select').val(),
|
|
notes: $('#consent-notes').val(),
|
|
is_urgent: $('#urgent-consent').is(':checked'),
|
|
send_notification: $('#send-notification').is(':checked')
|
|
};
|
|
|
|
if (!formData.patient || !formData.consent_form) {
|
|
toastr.error('Please select both patient and consent form');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: '{% url "patients:request_patient_consent" %}',
|
|
method: 'POST',
|
|
data: formData,
|
|
success: function(response) {
|
|
$('#requestConsentModal').modal('hide');
|
|
toastr.success('Consent request sent successfully');
|
|
refreshData();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to send consent request');
|
|
}
|
|
});
|
|
}
|
|
|
|
function signConsent(consentId) {
|
|
window.location.href = '{% url "patients:sign_patient_consent" 0 %}'.replace('0', consentId);
|
|
}
|
|
|
|
function viewDocument(consentId) {
|
|
window.open('{% url "patients:patient_consent_document" 0 %}'.replace('0', consentId), '_blank');
|
|
}
|
|
|
|
function sendReminder(consentId) {
|
|
if (confirm('Send reminder to patient?')) {
|
|
$.ajax({
|
|
url: '{% url "patients:send_consent_reminder" 0 %}'.replace('0', consentId),
|
|
method: 'POST',
|
|
success: function() {
|
|
toastr.success('Reminder sent successfully');
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to send reminder');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function renewConsent(consentId) {
|
|
if (confirm('Create renewal request for this consent?')) {
|
|
$.ajax({
|
|
url: '{% url "patients:renew_patient_consent" 0 %}'.replace('0', consentId),
|
|
method: 'POST',
|
|
success: function() {
|
|
toastr.success('Renewal request created');
|
|
refreshData();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to create renewal request');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function revokeConsent(consentId) {
|
|
if (confirm('Revoke this consent? This action cannot be undone.')) {
|
|
$.ajax({
|
|
url: '{% url "patients:revoke_patient_consent" 0 %}'.replace('0', consentId),
|
|
method: 'POST',
|
|
success: function() {
|
|
toastr.success('Consent revoked successfully');
|
|
refreshData();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to revoke consent');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function downloadConsent(consentId) {
|
|
window.open('{% url "patients:download_patient_consent" 0 %}'.replace('0', consentId), '_blank');
|
|
}
|
|
|
|
function printConsent(consentId) {
|
|
window.open('{% url "patients:print_patient_consent" 0 %}'.replace('0', consentId), '_blank');
|
|
}
|
|
|
|
function exportConsents() {
|
|
var selectedConsents = $('.consent-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
if (selectedConsents.length === 0) {
|
|
toastr.warning('Please select consents to export');
|
|
return;
|
|
}
|
|
|
|
var url = '{% url "patients:export_patient_consents" %}?consents=' + selectedConsents.join(',');
|
|
window.open(url, '_blank');
|
|
}
|
|
|
|
function bulkApprove() {
|
|
var selectedConsents = $('.consent-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
if (selectedConsents.length === 0) {
|
|
toastr.warning('Please select consents to approve');
|
|
return;
|
|
}
|
|
|
|
if (confirm('Approve ' + selectedConsents.length + ' selected consent(s)?')) {
|
|
$.ajax({
|
|
url: '{% url "patients:bulk_approve_consents" %}',
|
|
method: 'POST',
|
|
data: { consents: selectedConsents },
|
|
success: function() {
|
|
toastr.success('Consents approved successfully');
|
|
refreshData();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to approve consents');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function bulkRemind() {
|
|
var selectedConsents = $('.consent-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
if (selectedConsents.length === 0) {
|
|
toastr.warning('Please select consents to send reminders');
|
|
return;
|
|
}
|
|
|
|
if (confirm('Send reminders for ' + selectedConsents.length + ' selected consent(s)?')) {
|
|
$.ajax({
|
|
url: '{% url "patients:bulk_send_consent_reminders" %}',
|
|
method: 'POST',
|
|
data: { consents: selectedConsents },
|
|
success: function() {
|
|
toastr.success('Reminders sent successfully');
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to send reminders');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function bulkExport() {
|
|
exportConsents();
|
|
}
|
|
|
|
function bulkRevoke() {
|
|
var selectedConsents = $('.consent-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
if (selectedConsents.length === 0) {
|
|
toastr.warning('Please select consents to revoke');
|
|
return;
|
|
}
|
|
|
|
if (confirm('Revoke ' + selectedConsents.length + ' selected consent(s)? This action cannot be undone.')) {
|
|
$.ajax({
|
|
url: '{% url "patients:bulk_revoke_consents" %}',
|
|
method: 'POST',
|
|
data: { consents: selectedConsents },
|
|
success: function() {
|
|
toastr.success('Consents revoked successfully');
|
|
refreshData();
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to revoke consents');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|