Marwan Alwali 09932ffe8a update
2025-09-06 16:22:28 +03:00

244 lines
14 KiB
HTML

<div class="card">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover mb-0">
<thead class="table-light">
<tr>
<th>Date & Time</th>
<th>Patient</th>
<th>Provider</th>
<th>Type & Specialty</th>
<th>Status</th>
<th>Priority</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for appointment in appointments %}
<tr>
<td>
{% if appointment.scheduled_datetime %}
<div class="fw-bold">{{ appointment.scheduled_datetime|date:"M d, Y" }}</div>
<div class="text-muted">{{ appointment.scheduled_datetime|time:"g:i A" }}</div>
{% else %}
<div class="text-muted">Not scheduled</div>
{% endif %}
{% if appointment.is_telemedicine %}
<span class="badge bg-info mt-1">
<i class="fas fa-video"></i> Telemedicine
</span>
{% endif %}
</td>
<td>
<div class="fw-bold">{{ appointment.patient.get_full_name }}</div>
<div class="text-muted small">MRN: {{ appointment.patient.mrn }}</div>
{% if appointment.patient.date_of_birth %}
<div class="text-muted small">Age: {{ appointment.patient.age }}</div>
{% endif %}
</td>
<td>
<div>{{ appointment.provider.get_full_name }}</div>
<div class="text-muted small">{{ appointment.provider.get_role_display }}</div>
</td>
<td>
<div>{{ appointment.get_appointment_type_display }}</div>
<div class="text-muted small">{{ appointment.get_specialty_display }}</div>
<div class="text-muted small">{{ appointment.duration_minutes }} min</div>
</td>
<td>
{% if appointment.status == 'PENDING' %}
<span class="badge bg-secondary">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'SCHEDULED' %}
<span class="badge bg-primary">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'CONFIRMED' %}
<span class="badge bg-success">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'CHECKED_IN' %}
<span class="badge bg-warning">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'IN_PROGRESS' %}
<span class="badge bg-info">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'COMPLETED' %}
<span class="badge bg-success">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'CANCELLED' %}
<span class="badge bg-danger">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'NO_SHOW' %}
<span class="badge bg-dark">{{ appointment.get_status_display }}</span>
{% elif appointment.status == 'RESCHEDULED' %}
<span class="badge bg-warning">{{ appointment.get_status_display }}</span>
{% else %}
<span class="badge bg-light text-dark">{{ appointment.get_status_display }}</span>
{% endif %}
{% if appointment.is_overdue %}
<br><span class="badge bg-danger mt-1">Overdue</span>
{% endif %}
</td>
<td>
{% if appointment.priority == 'ROUTINE' %}
<span class="badge bg-light text-dark">{{ appointment.get_priority_display }}</span>
{% elif appointment.priority == 'URGENT' %}
<span class="badge bg-warning">{{ appointment.get_priority_display }}</span>
{% elif appointment.priority == 'STAT' %}
<span class="badge bg-danger">{{ appointment.get_priority_display }}</span>
{% elif appointment.priority == 'EMERGENCY' %}
<span class="badge bg-danger">{{ appointment.get_priority_display }}</span>
{% endif %}
{% if appointment.urgency_score > 5 %}
<br><small class="text-danger">Score: {{ appointment.urgency_score }}/10</small>
{% else %}
<br><small class="text-muted">Score: {{ appointment.urgency_score }}/10</small>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<!-- Check In Button -->
{% if appointment.status == 'SCHEDULED' or appointment.status == 'CONFIRMED' %}
<a type="button"
class="btn btn-outline-success"
title="Check In Patient"
href="{% url 'appointments:check_in_patient' appointment.id %}">
<i class="fas fa-check"></i>
</a>
{% endif %}
<!-- Telemedicine Join Button -->
{% if appointment.is_telemedicine and appointment.status in 'CHECKED_IN,IN_PROGRESS' and appointment.meeting_url %}
<button type="button"
class="btn btn-outline-primary"
title="Join Telemedicine Session"
onclick="window.open('{{ appointment.meeting_url }}', '_blank')">
<i class="fas fa-video"></i>
</button>
{% endif %}
<!-- Complete Button -->
{% if appointment.status == 'IN_PROGRESS' %}
<button type="button"
class="btn btn-outline-success"
title="Complete Appointment"
hx-post="{% url 'appointments:complete_appointment' appointment.id %}"
hx-target="#appointment-list"
hx-swap="outerHTML"
hx-confirm="Are you sure you want to complete this appointment?">
<i class="fas fa-check-circle"></i>
</button>
{% endif %}
<!-- Reschedule Button -->
{% if appointment.status in 'PENDING,SCHEDULED,CONFIRMED' %}
<button type="button"
class="btn btn-outline-warning"
title="Reschedule Appointment"
data-bs-toggle="modal"
data-bs-target="#rescheduleModal"
data-appointment-id="{{ appointment.id }}">
<i class="fas fa-calendar-alt"></i>
</button>
{% endif %}
<!-- View Details Button -->
<a href="{% url 'appointments:appointment_detail' appointment.pk %}"
class="btn btn-outline-info"
title="View Details">
<i class="fas fa-eye"></i>
</a>
<!-- More Actions Dropdown -->
<div class="btn-group btn-group-sm" role="group">
<button type="button"
class="btn btn-outline-secondary dropdown-toggle"
data-bs-toggle="dropdown"
aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#"><i class="fas fa-edit"></i> Edit</a></li>
<li><a class="dropdown-item" href="#"><i class="fas fa-copy"></i> Duplicate</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="fas fa-times"></i> Cancel</a></li>
</ul>
</div>
</div>
</td>
</tr>
{% empty %}
<tr>
<td colspan="7" class="text-center text-muted py-5">
<i class="fas fa-calendar fa-3x mb-3"></i>
<h5>No appointments found</h5>
<p>Try adjusting your search criteria or schedule a new appointment.</p>
<button type="button" class="btn btn-primary">
<i class="fas fa-calendar-plus"></i> Schedule New Appointment
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Reschedule Modal -->
<div class="modal fade" id="rescheduleModal" tabindex="-1" aria-labelledby="rescheduleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="rescheduleModalLabel">
<i class="fas fa-calendar-alt"></i> Reschedule Appointment
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="rescheduleForm">
<div class="mb-3">
<label for="newDateTime" class="form-label">New Date & Time</label>
<input type="datetime-local" class="form-control" id="newDateTime" name="new_datetime" required>
</div>
<div class="mb-3">
<label for="rescheduleReason" class="form-label">Reason for Rescheduling</label>
<textarea class="form-control" id="rescheduleReason" name="reason" rows="3" placeholder="Optional reason for rescheduling..."></textarea>
</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" id="confirmReschedule">
<i class="fas fa-calendar-alt"></i> Reschedule
</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Handle reschedule modal
const rescheduleModal = document.getElementById('rescheduleModal');
const confirmRescheduleBtn = document.getElementById('confirmReschedule');
let currentAppointmentId = null;
rescheduleModal.addEventListener('show.bs.modal', function(event) {
const button = event.relatedTarget;
currentAppointmentId = button.getAttribute('data-appointment-id');
});
confirmRescheduleBtn.addEventListener('click', function() {
if (currentAppointmentId) {
const form = document.getElementById('rescheduleForm');
const formData = new FormData(form);
htmx.ajax('POST', `/appointments/reschedule/${currentAppointmentId}/`, {
values: Object.fromEntries(formData),
target: '#appointment-list',
swap: 'outerHTML'
}).then(() => {
bootstrap.Modal.getInstance(rescheduleModal).hide();
});
}
});
});
</script>