261 lines
14 KiB
HTML
261 lines
14 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Reschedule Appointment{% endblock %}
|
|
|
|
{% block css %}
|
|
<link href="{% static 'assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-xl-8">
|
|
<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"><a href="{% url 'appointments:appointment_detail' appointment.id %}">{{ appointment.patient.first_name }} {{ appointment.patient.last_name }}</a></li>
|
|
<li class="breadcrumb-item active">Reschedule</li>
|
|
</ul>
|
|
|
|
<h1 class="page-header">Reschedule Appointment</h1>
|
|
|
|
<!-- Current Appointment Info -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">Current Appointment</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Patient:</strong></div>
|
|
<div class="col-8">{{ appointment.patient.first_name }} {{ appointment.patient.last_name }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Provider:</strong></div>
|
|
<div class="col-8">{{ appointment.provider.first_name }} {{ appointment.provider.last_name }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Department:</strong></div>
|
|
<div class="col-8">{{ appointment.department.name }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Date:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_date|date:"M d, Y" }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Time:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_time|time:"g:i A" }}</div>
|
|
</div>
|
|
<div class="row mb-2">
|
|
<div class="col-4"><strong>Type:</strong></div>
|
|
<div class="col-8">{{ appointment.appointment_type.name }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Reschedule Form -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h4 class="card-title">New Appointment Details</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 %}
|
|
|
|
<form method="post" class="form-horizontal">
|
|
{% csrf_token %}
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">New Date <span class="text-danger">*</span></label>
|
|
<div class="col-md-9">
|
|
<input type="date" name="new_date" class="form-control" required
|
|
min="{{ today|date:'Y-m-d' }}" value="{{ form.new_date.value|default:'' }}">
|
|
{% if form.new_date.errors %}
|
|
<div class="text-danger">{{ form.new_date.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">New Time <span class="text-danger">*</span></label>
|
|
<div class="col-md-9">
|
|
<input type="time" name="new_time" class="form-control" required
|
|
value="{{ form.new_time.value|default:'' }}">
|
|
{% if form.new_time.errors %}
|
|
<div class="text-danger">{{ form.new_time.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Provider</label>
|
|
<div class="col-md-9">
|
|
<select name="new_provider" class="form-select">
|
|
<option value="">Keep Current Provider</option>
|
|
{% for provider in providers %}
|
|
<option value="{{ provider.id }}"
|
|
{% if form.new_provider.value == provider.id|stringformat:"s" %}selected{% endif %}>
|
|
{{ provider.first_name }} {{ provider.last_name }} - {{ provider.department.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
{% if form.new_provider.errors %}
|
|
<div class="text-danger">{{ form.new_provider.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Reason for Rescheduling <span class="text-danger">*</span></label>
|
|
<div class="col-md-9">
|
|
<select name="reschedule_reason" class="form-select" required>
|
|
<option value="">Select Reason</option>
|
|
<option value="patient_request" {% if form.reschedule_reason.value == 'patient_request' %}selected{% endif %}>Patient Request</option>
|
|
<option value="provider_unavailable" {% if form.reschedule_reason.value == 'provider_unavailable' %}selected{% endif %}>Provider Unavailable</option>
|
|
<option value="emergency" {% if form.reschedule_reason.value == 'emergency' %}selected{% endif %}>Emergency</option>
|
|
<option value="equipment_issue" {% if form.reschedule_reason.value == 'equipment_issue' %}selected{% endif %}>Equipment Issue</option>
|
|
<option value="weather" {% if form.reschedule_reason.value == 'weather' %}selected{% endif %}>Weather</option>
|
|
<option value="other" {% if form.reschedule_reason.value == 'other' %}selected{% endif %}>Other</option>
|
|
</select>
|
|
{% if form.reschedule_reason.errors %}
|
|
<div class="text-danger">{{ form.reschedule_reason.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<label class="col-form-label col-md-3">Notes</label>
|
|
<div class="col-md-9">
|
|
<textarea name="reschedule_notes" class="form-control" rows="3"
|
|
placeholder="Additional notes about the rescheduling">{{ form.reschedule_notes.value|default:'' }}</textarea>
|
|
{% if form.reschedule_notes.errors %}
|
|
<div class="text-danger">{{ form.reschedule_notes.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-9 offset-md-3">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="notify_patient" id="notify_patient"
|
|
{% if form.notify_patient.value %}checked{% endif %}>
|
|
<label class="form-check-label" for="notify_patient">
|
|
Send notification to patient about the rescheduled appointment
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-9 offset-md-3">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fa fa-calendar me-2"></i>Reschedule Appointment
|
|
</button>
|
|
<a href="{% url 'appointments:appointment_detail' appointment.id %}" class="btn btn-secondary ms-2">Cancel</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Available Time Slots -->
|
|
<div class="card mt-4" id="availableSlotsCard" style="display: none;">
|
|
<div class="card-header">
|
|
<h4 class="card-title">Available Time Slots</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="availableSlots">
|
|
<!-- Time slots will be loaded here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script src="{% static 'assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize date picker
|
|
$('input[type="date"]').datepicker({
|
|
format: 'yyyy-mm-dd',
|
|
startDate: 'today',
|
|
autoclose: true
|
|
});
|
|
|
|
// Load available slots when date or provider changes
|
|
$('input[name="new_date"], select[name="new_provider"]').change(function() {
|
|
loadAvailableSlots();
|
|
});
|
|
});
|
|
|
|
function loadAvailableSlots() {
|
|
var date = $('input[name="new_date"]').val();
|
|
var provider = $('select[name="new_provider"]').val() || '{{ appointment.provider.id }}';
|
|
|
|
if (!date) return;
|
|
|
|
$.ajax({
|
|
url: '{% url "appointments:get_available_slots" %}',
|
|
data: {
|
|
'date': date,
|
|
'provider': provider,
|
|
'exclude_appointment': '{{ appointment.id }}'
|
|
},
|
|
success: function(data) {
|
|
var slotsHtml = '';
|
|
if (data.slots && data.slots.length > 0) {
|
|
slotsHtml += '<div class="row">';
|
|
data.slots.forEach(function(slot, index) {
|
|
if (index % 4 === 0 && index > 0) {
|
|
slotsHtml += '</div><div class="row mt-2">';
|
|
}
|
|
slotsHtml += '<div class="col-md-3">';
|
|
slotsHtml += '<button type="button" class="btn btn-outline-primary btn-sm w-100 time-slot" data-time="' + slot + '">';
|
|
slotsHtml += slot;
|
|
slotsHtml += '</button>';
|
|
slotsHtml += '</div>';
|
|
});
|
|
slotsHtml += '</div>';
|
|
|
|
$('#availableSlots').html(slotsHtml);
|
|
$('#availableSlotsCard').show();
|
|
|
|
// Add click handler for time slots
|
|
$('.time-slot').click(function() {
|
|
var time = $(this).data('time');
|
|
$('input[name="new_time"]').val(time);
|
|
$('.time-slot').removeClass('btn-primary').addClass('btn-outline-primary');
|
|
$(this).removeClass('btn-outline-primary').addClass('btn-primary');
|
|
});
|
|
} else {
|
|
$('#availableSlots').html('<p class="text-muted text-center">No available slots for this date</p>');
|
|
$('#availableSlotsCard').show();
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#availableSlots').html('<p class="text-danger text-center">Error loading available slots</p>');
|
|
$('#availableSlotsCard').show();
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|