349 lines
18 KiB
HTML
349 lines
18 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}
|
|
{% if object %}Edit Appointment Request{% else %}New Appointment Request{% endif %} - Appointments
|
|
{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.form-floating > .form-control:focus ~ label,
|
|
.form-floating > .form-control:not(:placeholder-shown) ~ label {
|
|
opacity: .65;
|
|
transform: scale(.85) translateY(-0.5rem) translateX(0.15rem);
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Breadcrumb -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
|
|
<h4 class="mb-sm-0">{% if object %}Edit Appointment Request{% else %}New Appointment Request{% endif %}</h4>
|
|
<div class="page-title-right">
|
|
<ol class="breadcrumb m-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'appointments:dashboard' %}">Appointments</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'appointments:appointment_list' %}">Requests</a></li>
|
|
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-calendar-plus me-2"></i>
|
|
Appointment Request Details
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="post" novalidate>
|
|
{% csrf_token %}
|
|
|
|
<!-- Patient Information -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-muted mb-3">Patient Information</h6>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="text-center mb-3">
|
|
{{ object.patient }}
|
|
</div>
|
|
{# <div class="form-floating mb-3">#}
|
|
{# {{ form.patient }}#}
|
|
{# <label for="{{ form.patient.id_for_label }}">Patient *</label>#}
|
|
{# {% if form.patient.errors %}#}
|
|
{# <div class="invalid-feedback d-block">#}
|
|
{# {{ form.patient.errors.0 }}#}
|
|
{# </div>#}
|
|
{# {% endif %}#}
|
|
{# </div>#}
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.provider }}
|
|
<label for="{{ form.provider.id_for_label }}">Provider *</label>
|
|
{% if form.provider.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.provider.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Appointment Details -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-muted mb-3">Appointment Details</h6>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.appointment_type }}
|
|
<label for="{{ form.appointment_type.id_for_label }}">Type *</label>
|
|
{% if form.appointment_type.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.appointment_type.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ 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>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.scheduled_datetime }}
|
|
<label for="{{ form.scheduled_datetime.id_for_label }}">Scheduled Date & Time *</label>
|
|
{% if form.scheduled_datetime.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.scheduled_datetime.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.duration_minutes }}
|
|
<label for="{{ form.duration_minutes.id_for_label }}">Duration (minutes) *</label>
|
|
{% if form.duration_minutes.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.duration_minutes.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional Information -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-muted mb-3">Additional Information</h6>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.department }}
|
|
<label for="{{ form.department.id_for_label }}">Department</label>
|
|
{% if form.department.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.department.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.location }}
|
|
<label for="{{ form.location.id_for_label }}">Location</label>
|
|
{% if form.location.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.location.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-floating mb-3">
|
|
{{ form.reason }}
|
|
<label for="{{ form.reason.id_for_label }}">Reason for Visit</label>
|
|
{% if form.reason.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.reason.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-floating mb-3">
|
|
{{ form.notes }}
|
|
<label for="{{ form.notes.id_for_label }}">Notes</label>
|
|
{% if form.notes.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.notes.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Options -->
|
|
<div class="row mb-4">
|
|
<div class="col-12">
|
|
<h6 class="text-muted mb-3">Options</h6>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
{{ form.is_telemedicine }}
|
|
<label class="form-check-label" for="{{ form.is_telemedicine.id_for_label }}">
|
|
Telemedicine Appointment
|
|
</label>
|
|
{% if form.is_telemedicine.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.is_telemedicine.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-3">
|
|
{{ form.send_reminders }}
|
|
<label class="form-check-label" for="{{ form.send_reminders.id_for_label }}">
|
|
Send Appointment Reminders
|
|
</label>
|
|
{% if form.send_reminders.errors %}
|
|
<div class="invalid-feedback d-block">
|
|
{{ form.send_reminders.errors.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="d-flex gap-2">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-1"></i>
|
|
{% if object %}Update Appointment{% else %}Create Appointment{% endif %}
|
|
</button>
|
|
<a href="{% url 'appointments:appointment_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-1"></i>
|
|
Cancel
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Help Sidebar -->
|
|
<div class="col-lg-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
Help & Guidelines
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="accordion" id="helpAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#appointmentTypes">
|
|
Appointment Types
|
|
</button>
|
|
</h2>
|
|
<div id="appointmentTypes" class="accordion-collapse collapse show" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><strong>Consultation:</strong> Initial patient visit</li>
|
|
<li><strong>Follow-up:</strong> Subsequent visits</li>
|
|
<li><strong>Procedure:</strong> Medical procedures</li>
|
|
<li><strong>Emergency:</strong> Urgent care</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#priorities">
|
|
Priority Levels
|
|
</button>
|
|
</h2>
|
|
<div id="priorities" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<ul class="list-unstyled mb-0">
|
|
<li><span class="badge bg-danger">High:</span> Urgent care needed</li>
|
|
<li><span class="badge bg-warning">Medium:</span> Standard priority</li>
|
|
<li><span class="badge bg-success">Low:</span> Routine appointment</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#telemedicine">
|
|
Telemedicine
|
|
</button>
|
|
</h2>
|
|
<div id="telemedicine" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<p class="mb-2">Enable for virtual consultations:</p>
|
|
<ul class="list-unstyled mb-0">
|
|
<li>• Patient must have video capability</li>
|
|
<li>• Provider must be available online</li>
|
|
<li>• Suitable for consultations only</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Auto-set duration based on appointment type
|
|
const typeField = document.getElementById('{{ form.appointment_type.id_for_label }}');
|
|
const durationField = document.getElementById('{{ form.duration_minutes.id_for_label }}');
|
|
|
|
if (typeField && durationField) {
|
|
typeField.addEventListener('change', function() {
|
|
const durations = {
|
|
'consultation': 30,
|
|
'follow_up': 15,
|
|
'procedure': 60,
|
|
'emergency': 45
|
|
};
|
|
|
|
if (durations[this.value] && !durationField.value) {
|
|
durationField.value = durations[this.value];
|
|
}
|
|
});
|
|
}
|
|
|
|
// Telemedicine location override
|
|
const telemedicineField = document.getElementById('{{ form.is_telemedicine.id_for_label }}');
|
|
const locationField = document.getElementById('{{ form.location.id_for_label }}');
|
|
|
|
if (telemedicineField && locationField) {
|
|
telemedicineField.addEventListener('change', function() {
|
|
if (this.checked) {
|
|
locationField.value = 'Virtual/Online';
|
|
locationField.readOnly = true;
|
|
} else {
|
|
if (locationField.value === 'Virtual/Online') {
|
|
locationField.value = '';
|
|
}
|
|
locationField.readOnly = false;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|