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

404 lines
21 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Appointment Reminders{% endblock %}
{% block css %}
<link href="{% static 'assets/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<div id="content" class="app-content">
<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'appointments:appointment_list' %}">Appointments</a></li>
<li class="breadcrumb-item active">Reminders</li>
</ul>
<div class="row align-items-center mb-3">
<div class="col">
<h1 class="page-header">Appointment Reminders</h1>
</div>
<div class="col-auto">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#sendRemindersModal">
<i class="fa fa-paper-plane me-2"></i>Send Reminders
</button>
</div>
</div>
<!-- Summary Cards -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6">
<div class="card border-0 text-truncate">
<div class="card-body">
<div class="row">
<div class="col-7">
<div class="text-dark fs-13px">Due Today</div>
<div class="text-dark fs-20px fw-600 lh-14">{{ reminders_due_today|length }}</div>
</div>
<div class="col-5">
<div class="mt-n1 mb-n1">
<div id="visitors-donut-chart" class="w-75 mx-auto"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card border-0 text-truncate">
<div class="card-body">
<div class="row">
<div class="col-7">
<div class="text-dark fs-13px">Sent Today</div>
<div class="text-dark fs-20px fw-600 lh-14">{{ reminders_sent_today|length }}</div>
</div>
<div class="col-5">
<div class="mt-n1 mb-n1">
<div class="w-75 mx-auto">
<i class="fa fa-check-circle fa-2x text-success"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card border-0 text-truncate">
<div class="card-body">
<div class="row">
<div class="col-7">
<div class="text-dark fs-13px">Failed</div>
<div class="text-dark fs-20px fw-600 lh-14">{{ reminders_failed|length }}</div>
</div>
<div class="col-5">
<div class="mt-n1 mb-n1">
<div class="w-75 mx-auto">
<i class="fa fa-exclamation-triangle fa-2x text-warning"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card border-0 text-truncate">
<div class="card-body">
<div class="row">
<div class="col-7">
<div class="text-dark fs-13px">Response Rate</div>
<div class="text-dark fs-20px fw-600 lh-14">{{ response_rate|floatformat:1 }}%</div>
</div>
<div class="col-5">
<div class="mt-n1 mb-n1">
<div class="w-75 mx-auto">
<i class="fa fa-chart-line fa-2x text-info"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="card mb-4">
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-3">
<label class="form-label">Date Range</label>
<select name="date_range" class="form-select">
<option value="today" {% if request.GET.date_range == 'today' %}selected{% endif %}>Today</option>
<option value="tomorrow" {% if request.GET.date_range == 'tomorrow' %}selected{% endif %}>Tomorrow</option>
<option value="week" {% if request.GET.date_range == 'week' %}selected{% endif %}>This Week</option>
<option value="month" {% if request.GET.date_range == 'month' %}selected{% endif %}>This Month</option>
<option value="all" {% if request.GET.date_range == 'all' %}selected{% endif %}>All</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Status</label>
<select name="status" class="form-select">
<option value="">All Statuses</option>
<option value="pending" {% if request.GET.status == 'pending' %}selected{% endif %}>Pending</option>
<option value="sent" {% if request.GET.status == 'sent' %}selected{% endif %}>Sent</option>
<option value="delivered" {% if request.GET.status == 'delivered' %}selected{% endif %}>Delivered</option>
<option value="failed" {% if request.GET.status == 'failed' %}selected{% endif %}>Failed</option>
<option value="responded" {% if request.GET.status == 'responded' %}selected{% endif %}>Responded</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">Method</label>
<select name="method" class="form-select">
<option value="">All Methods</option>
<option value="email" {% if request.GET.method == 'email' %}selected{% endif %}>Email</option>
<option value="sms" {% if request.GET.method == 'sms' %}selected{% endif %}>SMS</option>
<option value="phone" {% if request.GET.method == 'phone' %}selected{% endif %}>Phone</option>
<option value="push" {% if request.GET.method == 'push' %}selected{% endif %}>Push Notification</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">&nbsp;</label>
<div>
<button type="submit" class="btn btn-primary">
<i class="fa fa-search me-2"></i>Filter
</button>
<a href="{% url 'appointments:appointment_reminders' %}" class="btn btn-secondary ms-2">Reset</a>
</div>
</div>
</form>
</div>
</div>
<!-- Reminders Table -->
<div class="card">
<div class="card-header">
<h4 class="card-title">Reminder History</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 %}
<div class="table-responsive">
<table id="remindersTable" class="table table-striped table-bordered align-middle">
<thead>
<tr>
<th width="5%">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="selectAll">
</div>
</th>
<th>Patient</th>
<th>Appointment</th>
<th>Method</th>
<th>Status</th>
<th>Sent</th>
<th>Response</th>
<th width="10%">Actions</th>
</tr>
</thead>
<tbody>
{% for reminder in reminders %}
<tr>
<td>
<div class="form-check">
<input class="form-check-input reminder-checkbox" type="checkbox" value="{{ reminder.id }}">
</div>
</td>
<td>
<div class="d-flex align-items-center">
<div>
<div class="fw-bold">{{ reminder.appointment.patient.first_name }} {{ reminder.appointment.patient.last_name }}</div>
<div class="text-muted small">{{ reminder.appointment.patient.patient_id }}</div>
</div>
</div>
</td>
<td>
<div>
<div class="fw-bold">{{ reminder.appointment.appointment_date|date:"M d, Y" }}</div>
<div class="text-muted small">{{ reminder.appointment.appointment_time|time:"g:i A" }} - {{ reminder.appointment.provider.first_name }} {{ reminder.appointment.provider.last_name }}</div>
</div>
</td>
<td>
{% if reminder.method == 'email' %}
<span class="badge bg-primary"><i class="fa fa-envelope me-1"></i>Email</span>
{% elif reminder.method == 'sms' %}
<span class="badge bg-success"><i class="fa fa-sms me-1"></i>SMS</span>
{% elif reminder.method == 'phone' %}
<span class="badge bg-info"><i class="fa fa-phone me-1"></i>Phone</span>
{% elif reminder.method == 'push' %}
<span class="badge bg-warning"><i class="fa fa-bell me-1"></i>Push</span>
{% endif %}
</td>
<td>
{% if reminder.status == 'pending' %}
<span class="badge bg-secondary">Pending</span>
{% elif reminder.status == 'sent' %}
<span class="badge bg-primary">Sent</span>
{% elif reminder.status == 'delivered' %}
<span class="badge bg-success">Delivered</span>
{% elif reminder.status == 'failed' %}
<span class="badge bg-danger">Failed</span>
{% elif reminder.status == 'responded' %}
<span class="badge bg-info">Responded</span>
{% endif %}
</td>
<td>
{% if reminder.sent_at %}
<div>{{ reminder.sent_at|date:"M d, Y" }}</div>
<div class="text-muted small">{{ reminder.sent_at|time:"g:i A" }}</div>
{% else %}
<span class="text-muted">Not sent</span>
{% endif %}
</td>
<td>
{% if reminder.response_received_at %}
<div class="text-success">
<i class="fa fa-check me-1"></i>{{ reminder.response_received_at|date:"M d, Y" }}
</div>
{% else %}
<span class="text-muted">No response</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm">
{% if reminder.status == 'pending' or reminder.status == 'failed' %}
<button type="button" class="btn btn-outline-primary" onclick="resendReminder('{{ reminder.id }}')">
<i class="fa fa-redo"></i>
</button>
{% endif %}
<button type="button" class="btn btn-outline-info" onclick="viewReminderDetails('{{ reminder.id }}')">
<i class="fa fa-eye"></i>
</button>
</div>
</td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center text-muted py-4">
<i class="fa fa-inbox fa-3x mb-3"></i>
<div>No reminders found</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Send Reminders Modal -->
<div class="modal fade" id="sendRemindersModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Send Appointment Reminders</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form method="post" action="{% url 'appointments:send_reminders' %}">
<div class="modal-body">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">Reminder Type</label>
<select name="reminder_type" class="form-select" required>
<option value="24_hour">24 Hour Reminder</option>
<option value="2_hour">2 Hour Reminder</option>
<option value="custom">Custom</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">Send Method</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="methods" value="email" id="method_email" checked>
<label class="form-check-label" for="method_email">Email</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="methods" value="sms" id="method_sms">
<label class="form-check-label" for="method_sms">SMS</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="methods" value="push" id="method_push">
<label class="form-check-label" for="method_push">Push Notification</label>
</div>
</div>
<div class="mb-3">
<label class="form-label">Date Range</label>
<div class="row">
<div class="col-6">
<input type="date" name="start_date" class="form-control" required>
</div>
<div class="col-6">
<input type="date" name="end_date" class="form-control" required>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Custom Message (Optional)</label>
<textarea name="custom_message" class="form-control" rows="3"
placeholder="Additional message to include with the reminder"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-paper-plane me-2"></i>Send Reminders
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/datatables.net/js/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
<script src="{% static 'assets/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
<script>
$(document).ready(function() {
// Initialize DataTable
$('#remindersTable').DataTable({
responsive: true,
order: [[5, 'desc']],
columnDefs: [
{ orderable: false, targets: [0, 7] }
]
});
// Select all functionality
$('#selectAll').change(function() {
$('.reminder-checkbox').prop('checked', this.checked);
});
// Set default dates for reminder modal
var today = new Date();
var tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
var nextWeek = new Date(today);
nextWeek.setDate(nextWeek.getDate() + 7);
$('input[name="start_date"]').val(tomorrow.toISOString().split('T')[0]);
$('input[name="end_date"]').val(nextWeek.toISOString().split('T')[0]);
});
function resendReminder(reminderId) {
if (confirm('Are you sure you want to resend this reminder?')) {
$.post('{% url "appointments:resend_reminder" %}', {
'reminder_id': reminderId,
'csrfmiddlewaretoken': '{{ csrf_token }}'
}, function(data) {
if (data.success) {
location.reload();
} else {
alert('Failed to resend reminder: ' + data.error);
}
});
}
}
function viewReminderDetails(reminderId) {
// Implementation for viewing reminder details
window.open('{% url "appointments:reminder_detail" 0 %}'.replace('0', reminderId), '_blank');
}
</script>
{% endblock %}