623 lines
24 KiB
PHP
623 lines
24 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Patients</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
|
<link rel="stylesheet" href="<?= base_url('css/app.css') ?>">
|
|
<link rel="stylesheet" href="<?= base_url('css/dashboard.css') ?>">
|
|
<link rel="stylesheet" href="<?= base_url('css/doctors.css') ?>">
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css">
|
|
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css">
|
|
</head>
|
|
<body class="app-body overview-layout">
|
|
<aside class="ov-sidebar" id="sidebar">
|
|
<div class="ov-brand"><h1><i class="bi bi-hospital me-1"></i> DoctGuide</h1><span>Control Panel</span></div>
|
|
<nav class="ov-nav">
|
|
<div class="ov-nav__section">Main</div>
|
|
<a href="<?= base_url('admin/dashboard') ?>" class="ov-nav__link"><i class="bi bi-speedometer2"></i> Dashboard</a>
|
|
<div class="ov-nav__section">Manage</div>
|
|
<div class="ov-nav__dropdown">
|
|
<a href="#" class="ov-nav__link d-flex justify-content-between align-items-center" onclick="toggleNavDropdown(event, this)">
|
|
<span><i class="bi bi-person-badge"></i> Doctors</span>
|
|
<i class="bi bi-chevron-down dropdown-icon"></i>
|
|
</a>
|
|
<div class="ov-dropdown-menu">
|
|
<a href="<?= base_url('admin/doctors') ?>" class="ov-nav__sublink">Doctor List</a>
|
|
<a href="<?= base_url('admin/doctors/add') ?>" class="ov-nav__sublink">Add Doctor</a>
|
|
</div>
|
|
</div>
|
|
<div class="ov-nav__dropdown active">
|
|
<a href="#" class="ov-nav__link d-flex justify-content-between align-items-center" onclick="toggleNavDropdown(event, this)">
|
|
<span><i class="bi bi-people"></i> Patients</span>
|
|
<i class="bi bi-chevron-down dropdown-icon"></i>
|
|
</a>
|
|
<div class="ov-dropdown-menu">
|
|
<a href="<?= base_url('admin/patients') ?>" class="ov-nav__sublink">Patient List</a>
|
|
<a href="<?= base_url('admin/patients/add') ?>" class="ov-nav__sublink">Add Patient</a>
|
|
</div>
|
|
</div>
|
|
<a href="<?= base_url('admin/appointments') ?>" class="ov-nav__link"><i class="bi bi-calendar2-check"></i> Appointments</a>
|
|
<a href="<?= base_url('admin/activity-log') ?>" class="ov-nav__link"><i class="bi bi-clipboard-data"></i> Activity Log</a>
|
|
</nav>
|
|
<div class="ov-sidebar__footer"><a href="<?= base_url('logout') ?>"><i class="bi bi-box-arrow-left"></i> Logout</a></div>
|
|
</aside>
|
|
|
|
<div class="ov-main" id="mainContent">
|
|
<header class="ov-topbar">
|
|
<div class="d-flex align-items-center">
|
|
<button class="ov-toggle-btn" onclick="toggleSidebar()" title="Toggle Sidebar"><i class="bi bi-list" id="toggleIcon"></i></button>
|
|
<p class="ov-topbar__title mb-0">Patients</p>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="ov-content">
|
|
<?php if (session()->getFlashdata('success')): ?>
|
|
<div class="alert alert-success app-alert"><?= esc(session()->getFlashdata('success')) ?></div>
|
|
<?php endif; ?>
|
|
<?php if (session()->getFlashdata('error')): ?>
|
|
<div class="alert alert-danger app-alert"><?= esc(session()->getFlashdata('error')) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="ov-panel">
|
|
<div class="ov-panel__header">
|
|
<h2 class="ov-panel__title">Patient List</h2>
|
|
<div class="d-flex flex-wrap gap-2 align-items-center">
|
|
<div class="dropdown">
|
|
<button class="btn btn-outline-secondary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
<i class="bi bi-three-dots-vertical"></i>
|
|
</button>
|
|
<ul class="dropdown-menu dropdown-menu-end">
|
|
<li><a class="dropdown-item" href="#" onclick="exportTable('csv'); return false;"><i class="bi bi-file-earmark-text me-2"></i> CSV</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="exportTable('excel'); return false;"><i class="bi bi-file-earmark-excel me-2"></i> Excel</a></li>
|
|
<li><a class="dropdown-item" href="#" onclick="exportTable('pdf'); return false;"><i class="bi bi-file-earmark-pdf me-2"></i> PDF</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="p-0">
|
|
<table id="patientsTable" class="table table-hover" style="width:100%">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th width="60">User ID</th>
|
|
<th>Patient Name</th>
|
|
<th>Email</th>
|
|
<th>Phone</th>
|
|
<th width="120">Status</th>
|
|
<th width="130">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<!-- Appointment Modal -->
|
|
<div class="modal fade" id="appointmentModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Create Appointment</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
|
|
<form id="appointmentForm" method="POST" action="<?= base_url('admin/appointments/create') ?>">
|
|
|
|
<div class="modal-body">
|
|
|
|
<!-- Patient Info Section -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Formatted Patient ID</label>
|
|
<input type="text" id="apptFormattedId" class="form-control" readonly>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Patient Name</label>
|
|
<input type="text" id="apptName" class="form-control" readonly>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Service/Specialization -->
|
|
<div class="mb-3">
|
|
<label class="form-label">Service Request <span class="text-danger">*</span></label>
|
|
<select id="apptSpecialization" class="form-select" style="width:100%;" required>
|
|
<option value="">Select a specialization...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Date and Time -->
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label">Date <span class="text-danger">*</span></label>
|
|
<input type="date" id="apptDate" class="form-control" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">Time <span class="text-danger">*</span></label>
|
|
<input type="time" id="apptTime" class="form-control" required>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Doctors List -->
|
|
<div id="doctorsContainer" class="d-none mb-4">
|
|
<label class="form-label">Available Doctors <span class="text-danger">*</span></label>
|
|
<div class="row g-3" id="doctorsList"></div>
|
|
<input type="hidden" id="selectedDoctorId" name="doctor_id" required>
|
|
</div>
|
|
|
|
<!-- Note -->
|
|
<div class="mb-3">
|
|
<label class="form-label">Note</label>
|
|
<textarea id="apptNote" class="form-control" rows="3"></textarea>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-success" id="submitBtn" disabled>
|
|
<i class="bi bi-check-circle"></i> Save Appointment
|
|
</button>
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<style>
|
|
/* .modal-backdrop.show {
|
|
backdrop-filter: blur(8px);
|
|
-webkit-backdrop-filter: blur(8px);
|
|
background-color: rgba(0, 0, 0, 0.3) !important;
|
|
}
|
|
.modal-content {
|
|
background: rgba(255, 255, 255, 0.85);
|
|
backdrop-filter: blur(10px);
|
|
-webkit-backdrop-filter: blur(10px);
|
|
border-radius: 16px;
|
|
border: none;
|
|
} */
|
|
.modal.fade .modal-dialog {
|
|
transform: scale(0.9);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.modal.show .modal-dialog {
|
|
transform: scale(1);
|
|
}
|
|
</style>
|
|
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
|
|
<script src="https://cdn.datatables.net/1.13.7/js/dataTables.bootstrap5.min.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.bootstrap5.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script>
|
|
<script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.print.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
|
<script>
|
|
let patientsTable = null;
|
|
|
|
function escapeHtml(value) {
|
|
return String(value ?? '')
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
function toggleSidebar() {
|
|
const sidebar = document.getElementById('sidebar');
|
|
const main = document.getElementById('mainContent');
|
|
const icon = document.getElementById('toggleIcon');
|
|
sidebar.classList.toggle('collapsed');
|
|
main.classList.toggle('expanded');
|
|
icon.className = sidebar.classList.contains('collapsed') ? 'bi bi-layout-sidebar' : 'bi bi-list';
|
|
}
|
|
|
|
function toggleNavDropdown(event, element) {
|
|
event.preventDefault();
|
|
element.parentElement.classList.toggle('active');
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
patientsTable = $('#patientsTable').DataTable({
|
|
processing: true,
|
|
ajax: {
|
|
url: "<?= base_url('admin/patients/data') ?>",
|
|
type: 'GET',
|
|
dataSrc: 'data'
|
|
},
|
|
columns: [
|
|
{
|
|
data: 'formatted_user_id',
|
|
defaultContent: 'N/A'
|
|
},
|
|
{
|
|
data: 'name',
|
|
render: function (data) {
|
|
return `<div class="fw-medium">${escapeHtml(data ?? 'Unknown Patient')}</div>`;
|
|
}
|
|
},
|
|
{
|
|
data: 'email',
|
|
render: function (data) {
|
|
if (!data) {
|
|
return '<span class="text-muted">N/A</span>';
|
|
}
|
|
|
|
const safeEmail = escapeHtml(data);
|
|
return `<a href="mailto:${safeEmail}" class="text-decoration-none">${safeEmail}</a>`;
|
|
}
|
|
},
|
|
{
|
|
data: 'phone',
|
|
render: function (data) {
|
|
return data ? escapeHtml(data) : '<span class="text-muted">N/A</span>';
|
|
}
|
|
},
|
|
{
|
|
data: 'status',
|
|
render: function (data) {
|
|
const status = String(data ?? 'active').toLowerCase();
|
|
const statusClass = status === 'active' ? 'success' : 'secondary';
|
|
const label = status.charAt(0).toUpperCase() + status.slice(1);
|
|
|
|
return `
|
|
<span class="badge bg-${statusClass} rounded-pill">
|
|
<i class="bi bi-circle-fill me-1" style="font-size: 0.5rem;"></i>
|
|
${escapeHtml(label)}
|
|
</span>
|
|
`;
|
|
}
|
|
},
|
|
{
|
|
data: null,
|
|
orderable: false,
|
|
searchable: false,
|
|
render: function (data, type, row) {
|
|
|
|
const editUrl = "<?= base_url('admin/patients/edit') ?>/" + encodeURIComponent(row.edit_token);
|
|
|
|
const deleteUrl = "<?= base_url('admin/deletePatient') ?>/" + encodeURIComponent(row.user_id);
|
|
|
|
return `
|
|
<div class="btn-group" role="group">
|
|
<a href="${editUrl}" class="btn btn-outline-primary btn-sm">
|
|
<i class="bi bi-pencil"></i>
|
|
</a>
|
|
|
|
<a href="<?= base_url('admin/appointments/create-form') ?>/${row.user_id}"
|
|
class="btn btn-outline-success btn-sm"
|
|
title="Book Appointment">
|
|
<i class="bi bi-plus-lg"></i>
|
|
</a>
|
|
|
|
<a href="${deleteUrl}" class="btn btn-outline-danger btn-sm"
|
|
onclick="return confirm('Delete this patient?');">
|
|
<i class="bi bi-trash"></i>
|
|
</a>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
],
|
|
pageLength: 10,
|
|
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
|
|
order: [[0, 'asc']],
|
|
dom: '<"row mb-3"<"col-md-6 d-flex align-items-center"l><"col-md-6 d-flex justify-content-end"f>>rtip',
|
|
buttons: [
|
|
{
|
|
extend: 'csvHtml5',
|
|
className: 'buttons-csv',
|
|
title: 'Patients',
|
|
filename: 'patients_list_' + new Date().toISOString().split('T')[0],
|
|
exportOptions: {
|
|
columns: [0, 1, 2, 3, 4]
|
|
}
|
|
},
|
|
{
|
|
extend: 'excelHtml5',
|
|
className: 'buttons-excel',
|
|
title: 'Patients',
|
|
filename: 'patients_list_' + new Date().toISOString().split('T')[0],
|
|
exportOptions: {
|
|
columns: [0, 1, 2, 3, 4]
|
|
}
|
|
},
|
|
{
|
|
extend: 'pdfHtml5',
|
|
className: 'buttons-pdf',
|
|
title: 'Patients List',
|
|
filename: 'patients_list_' + new Date().toISOString().split('T')[0],
|
|
orientation: 'landscape',
|
|
pageSize: 'A4',
|
|
exportOptions: {
|
|
columns: [0, 1, 2, 3, 4]
|
|
}
|
|
}
|
|
],
|
|
language: {
|
|
search: 'Search patients:',
|
|
lengthMenu: 'Show _MENU_ patients',
|
|
info: 'Showing _START_ to _END_ of _TOTAL_ patients',
|
|
paginate: {
|
|
first: 'First',
|
|
last: 'Last',
|
|
next: 'Next',
|
|
previous: 'Previous'
|
|
},
|
|
emptyTable: 'No patients found',
|
|
zeroRecords: 'No matching patients found'
|
|
}
|
|
});
|
|
|
|
setInterval(function () {
|
|
if (patientsTable) {
|
|
patientsTable.ajax.reload(null, false);
|
|
}
|
|
}, 15000);
|
|
// $('#apptService').select2({
|
|
// placeholder: "Select or search service",
|
|
// dropdownParent: $('#appointmentModal'),
|
|
// allowClear: true,
|
|
// width: '100%'
|
|
// });
|
|
});
|
|
|
|
function exportTable(format) {
|
|
if (!patientsTable) {
|
|
return;
|
|
}
|
|
|
|
if (format === 'csv') {
|
|
patientsTable.button('.buttons-csv').trigger();
|
|
} else if (format === 'excel') {
|
|
patientsTable.button('.buttons-excel').trigger();
|
|
} else if (format === 'pdf') {
|
|
patientsTable.button('.buttons-pdf').trigger();
|
|
}
|
|
}
|
|
// $(document).on('click', '.open-appointment-modal', function () {
|
|
// const userId = $(this).data('id');
|
|
// const name = $(this).data('name');
|
|
|
|
// $('#apptUserId').val(userId);
|
|
// $('#apptName').val(name);
|
|
|
|
// // ✅ Reset fields
|
|
// $('#apptService').val(null).trigger('change');
|
|
// $('#apptTiming').val('');
|
|
// $('#apptNote').val('');
|
|
|
|
// const modal = new bootstrap.Modal(document.getElementById('appointmentModal'));
|
|
// modal.show();
|
|
// });
|
|
|
|
// Load specializations on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadSpecializations();
|
|
const dateInput = document.getElementById('apptDate');
|
|
if (dateInput) {
|
|
dateInput.min = new Date().toISOString().slice(0, 10);
|
|
}
|
|
|
|
// Handle date and time change
|
|
document.getElementById('apptDate').addEventListener('change', fetchAvailableDoctors);
|
|
document.getElementById('apptTime').addEventListener('change', fetchAvailableDoctors);
|
|
document.getElementById('apptSpecialization').addEventListener('change', fetchAvailableDoctors);
|
|
|
|
// Handle form submission
|
|
document.getElementById('appointmentForm').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
submitAppointmentForm();
|
|
});
|
|
});
|
|
|
|
function escapeHtml(value) {
|
|
return String(value ?? '')
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''');
|
|
}
|
|
|
|
function loadSpecializations() {
|
|
fetch('<?= base_url('admin/specializations') ?>', {
|
|
method: 'GET',
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.specializations.length > 0) {
|
|
const specSelect = document.getElementById('apptSpecialization');
|
|
specSelect.innerHTML = '<option value="">Select a specialization...</option>';
|
|
|
|
data.specializations.forEach(spec => {
|
|
const option = document.createElement('option');
|
|
option.value = spec.id;
|
|
option.textContent = spec.name;
|
|
specSelect.appendChild(option);
|
|
});
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error loading specializations:', error);
|
|
});
|
|
}
|
|
|
|
function openAppointmentModal(userId, formattedId, patientName) {
|
|
// Reset form
|
|
document.getElementById('appointmentForm').reset();
|
|
document.getElementById('apptFormattedId').value = formattedId;
|
|
document.getElementById('apptName').value = patientName;
|
|
document.getElementById('selectedDoctorId').value = '';
|
|
document.getElementById('doctorsContainer').classList.add('d-none');
|
|
document.getElementById('submitBtn').disabled = true;
|
|
|
|
// Store user ID for later use
|
|
document.getElementById('appointmentForm').dataset.userId = userId;
|
|
|
|
// Show modal
|
|
const modal = new bootstrap.Modal(document.getElementById('appointmentModal'));
|
|
modal.show();
|
|
}
|
|
|
|
function fetchAvailableDoctors() {
|
|
const date = document.getElementById('apptDate').value;
|
|
const time = document.getElementById('apptTime').value;
|
|
const specializationId = document.getElementById('apptSpecialization').value;
|
|
|
|
if (!date || !time || !specializationId) {
|
|
document.getElementById('doctorsContainer').classList.add('d-none');
|
|
document.getElementById('submitBtn').disabled = true;
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData();
|
|
formData.append('date', date);
|
|
formData.append('time', time);
|
|
formData.append('specialization_id', specializationId);
|
|
|
|
fetch('<?= base_url('admin/available-doctors') ?>', {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.doctors.length > 0) {
|
|
displayDoctors(data.doctors);
|
|
document.getElementById('doctorsContainer').classList.remove('d-none');
|
|
} else {
|
|
document.getElementById('doctorsContainer').classList.add('d-none');
|
|
document.getElementById('submitBtn').disabled = true;
|
|
alert('No doctors available for the selected date, time, and specialization.');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while fetching doctors.');
|
|
});
|
|
}
|
|
|
|
function displayDoctors(doctors) {
|
|
const doctorsList = document.getElementById('doctorsList');
|
|
doctorsList.innerHTML = '';
|
|
|
|
doctors.forEach(doctor => {
|
|
const col = document.createElement('div');
|
|
col.className = 'col-md-6';
|
|
|
|
const card = document.createElement('div');
|
|
const statusClass = doctor.is_available ? '' : 'opacity-50';
|
|
card.className = `border rounded-3 p-3 doctor-card ${statusClass}`;
|
|
|
|
if (!doctor.is_available) {
|
|
card.style.pointerEvents = 'none';
|
|
}
|
|
|
|
card.innerHTML = `
|
|
<div class="form-check">
|
|
<input class="form-check-input doctor-radio" type="radio" name="doctorSelection" id="doctor_${doctor.id}"
|
|
value="${doctor.id}" ${!doctor.is_available ? 'disabled' : ''}>
|
|
<label class="form-check-label w-100" for="doctor_${doctor.id}">
|
|
<h6 class="mb-1">Dr. ${escapeHtml(doctor.name)}</h6>
|
|
<p class="text-muted small mb-0">${doctor.is_available ? '✓ Available' : '✗ Not Available'}</p>
|
|
</label>
|
|
</div>
|
|
`;
|
|
|
|
col.appendChild(card);
|
|
doctorsList.appendChild(col);
|
|
|
|
// Add click listener to radio buttons
|
|
document.getElementById(`doctor_${doctor.id}`).addEventListener('change', function() {
|
|
if (this.checked) {
|
|
document.getElementById('selectedDoctorId').value = this.value;
|
|
document.getElementById('submitBtn').disabled = false;
|
|
highlightSelectedDoctor(doctor.id);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function highlightSelectedDoctor(doctorId) {
|
|
document.querySelectorAll('.doctor-card').forEach(card => {
|
|
card.classList.remove('border-primary', 'bg-light');
|
|
});
|
|
|
|
const selectedCard = document.getElementById(`doctor_${doctorId}`).closest('.doctor-card');
|
|
if (selectedCard) {
|
|
selectedCard.classList.add('border-primary', 'bg-light');
|
|
}
|
|
}
|
|
|
|
function submitAppointmentForm() {
|
|
const form = document.getElementById('appointmentForm');
|
|
const userId = parseInt(form.dataset.userId);
|
|
const doctorId = parseInt(document.getElementById('selectedDoctorId').value);
|
|
const date = document.getElementById('apptDate').value;
|
|
const time = document.getElementById('apptTime').value;
|
|
const note = document.getElementById('apptNote').value;
|
|
|
|
if (!userId || !doctorId || !date || !time) {
|
|
alert('Please select all required fields.');
|
|
return;
|
|
}
|
|
|
|
if (new Date(date + 'T' + time) < new Date()) {
|
|
alert('Past date or time booking is not allowed.');
|
|
return;
|
|
}
|
|
|
|
const submitData = {
|
|
patient_id: userId,
|
|
doctor_id: doctorId,
|
|
appointment_date: date,
|
|
appointment_time: time,
|
|
note: note
|
|
};
|
|
|
|
fetch('<?= base_url('admin/appointments/create') ?>', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify(submitData)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert('Appointment booked successfully!');
|
|
const modal = bootstrap.Modal.getInstance(document.getElementById('appointmentModal'));
|
|
modal.hide();
|
|
location.reload();
|
|
} else {
|
|
alert(data.message || 'Failed to book appointment.');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while booking the appointment.');
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|