Spaces:
Sleeping
Sleeping
Update templates/doctor_dashboard.html
Browse files- templates/doctor_dashboard.html +458 -173
templates/doctor_dashboard.html
CHANGED
|
@@ -54,14 +54,28 @@
|
|
| 54 |
background-color: #2e59d9; /* Darker blue */
|
| 55 |
border-color: #2653d4;
|
| 56 |
}
|
| 57 |
-
|
| 58 |
background-color: var(--secondary-color);
|
| 59 |
border-color: var(--secondary-color);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
}
|
| 61 |
.btn-danger {
|
| 62 |
background-color: var(--danger-color);
|
| 63 |
border-color: var(--danger-color);
|
| 64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
.role-toggle {
|
| 66 |
display: flex;
|
| 67 |
align-items: center;
|
|
@@ -112,7 +126,6 @@
|
|
| 112 |
box-shadow: 0 0.3rem 0.8rem 0 rgba(58, 59, 69, 0.1);
|
| 113 |
background-color: #fcfcfc; /* Slightly lighter hover background */
|
| 114 |
}
|
| 115 |
-
|
| 116 |
.patient-item.active {
|
| 117 |
border: 1px solid var(--primary-color); /* Highlight active item */
|
| 118 |
border-left: 4px solid var(--primary-color);
|
|
@@ -133,7 +146,6 @@
|
|
| 133 |
.patient-item.unknown { /* Style for unknown status in list */
|
| 134 |
border-left-color: var(--dark-color);
|
| 135 |
}
|
| 136 |
-
|
| 137 |
.patient-status {
|
| 138 |
padding: 0.3rem 0.8rem; /* Slightly larger padding */
|
| 139 |
border-radius: 50rem;
|
|
@@ -164,7 +176,7 @@
|
|
| 164 |
margin-top: 1.5rem;
|
| 165 |
}
|
| 166 |
.care-plan-content {
|
| 167 |
-
background-color:
|
| 168 |
border-radius: 0 0 0.35rem 0.35rem; /* Rounded corners at bottom */
|
| 169 |
border: 1px solid var(--border-color);
|
| 170 |
border-top: none; /* No border top because of tabs */
|
|
@@ -177,6 +189,18 @@
|
|
| 177 |
font-size: 1rem;
|
| 178 |
color: #333;
|
| 179 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
.patient-details-section {
|
| 181 |
display: none; /* Hidden by default */
|
| 182 |
}
|
|
@@ -213,6 +237,10 @@
|
|
| 213 |
#patient-feedback {
|
| 214 |
background-color: #e9ecef; /* Light grey */
|
| 215 |
border-color: #dee2e6; /* Light grey border */
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
}
|
| 217 |
/* Delete button styling */
|
| 218 |
.delete-patient-btn {
|
|
@@ -240,6 +268,36 @@
|
|
| 240 |
.patient-item > div:first-child {
|
| 241 |
margin-right: 2rem; /* Add margin to the content to make space for the button */
|
| 242 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
</style>
|
| 244 |
</head>
|
| 245 |
<body>
|
|
@@ -260,12 +318,19 @@
|
|
| 260 |
</li>
|
| 261 |
<li class="nav-item">
|
| 262 |
<div class="role-toggle">
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
</div>
|
| 270 |
</li>
|
| 271 |
</ul>
|
|
@@ -328,28 +393,56 @@
|
|
| 328 |
<p id="patient-feedback" class="p-3 bg-light rounded border"></p>
|
| 329 |
</div>
|
| 330 |
|
| 331 |
-
|
| 332 |
<strong>Last Updated:</strong> <span id="patient-timestamp"></span>
|
| 333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 334 |
|
| 335 |
-
<!-- Download button now relies on patient ID -->
|
| 336 |
-
<button class="btn btn-primary" id="download-pdf">
|
| 337 |
-
<i class="fas fa-file-download me-2"></i>Download Care Plan PDF
|
| 338 |
-
</button>
|
| 339 |
|
| 340 |
<div class="care-plan-tabs mt-4">
|
| 341 |
<ul class="nav nav-tabs" id="carePlanTabs" role="tablist">
|
| 342 |
<li class="nav-item" role="presentation">
|
| 343 |
-
<button class="nav-link active" id="updated-plan-tab" data-bs-toggle="tab" data-bs-target="#updated-plan" type="button" role="tab" aria-controls="updated-plan" aria-selected="true">Updated Care Plan</button>
|
| 344 |
</li>
|
| 345 |
<li class="nav-item" role="presentation">
|
| 346 |
<button class="nav-link" id="original-plan-tab" data-bs-toggle="tab" data-bs-target="#original-plan" type="button" role="tab" aria-controls="original-plan" aria-selected="false">Original Care Plan</button>
|
| 347 |
</li>
|
| 348 |
</ul>
|
| 349 |
<div class="tab-content" id="carePlanTabsContent">
|
| 350 |
-
|
| 351 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
</div>
|
|
|
|
|
|
|
| 353 |
<div class="tab-pane fade" id="original-plan" role="tabpanel" aria-labelledby="original-plan-tab">
|
| 354 |
<div class="care-plan-content" id="original-plan-content"></div>
|
| 355 |
</div>
|
|
@@ -371,12 +464,25 @@
|
|
| 371 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
| 372 |
<script>
|
| 373 |
$(document).ready(function() {
|
| 374 |
-
// Set active role button on load
|
| 375 |
-
$('.role-toggle-btn[data-role="doctor"]').addClass('active');
|
| 376 |
-
$('.role-toggle-btn[data-role="patient"]').removeClass('active');
|
| 377 |
|
| 378 |
// Placeholder for storing selected patient ID
|
| 379 |
let currentlySelectedPatientId = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
|
| 381 |
// Load all patients
|
| 382 |
function loadPatients() {
|
|
@@ -385,7 +491,6 @@
|
|
| 385 |
$('#no-patients-found').hide();
|
| 386 |
$('#patient-list-error').hide(); // Hide previous error
|
| 387 |
$('#patient-list').empty(); // Clear current list
|
| 388 |
-
|
| 389 |
$.ajax({
|
| 390 |
url: '/get_patients',
|
| 391 |
type: 'GET',
|
|
@@ -395,7 +500,6 @@
|
|
| 395 |
console.log("Patients loaded:", response.patients.length);
|
| 396 |
// Update patient count
|
| 397 |
$('#patient-count').text(response.patients.length);
|
| 398 |
-
|
| 399 |
// Sort patients by status priority (Emergency first) then timestamp (newest first)
|
| 400 |
const statusPriority = { 'emergency': 0, 'deteriorating': 1, 'improving': 2, 'stable': 3, 'unknown': 4 };
|
| 401 |
const sortedPatients = response.patients.sort((a, b) => {
|
|
@@ -408,7 +512,6 @@
|
|
| 408 |
const dateB = new Date(b.timestamp || '1900-01-01T00:00:00Z'); // Handle missing timestamp
|
| 409 |
return dateB - dateA; // Newest first
|
| 410 |
});
|
| 411 |
-
|
| 412 |
// Populate emergency alerts
|
| 413 |
const emergencyPatients = sortedPatients.filter(p => p.status === 'emergency');
|
| 414 |
if (emergencyPatients.length > 0) {
|
|
@@ -422,7 +525,6 @@
|
|
| 422 |
} else {
|
| 423 |
$('#emergency-alerts').empty();
|
| 424 |
}
|
| 425 |
-
|
| 426 |
// Populate patient list
|
| 427 |
sortedPatients.forEach(patient => {
|
| 428 |
const statusText = {
|
|
@@ -454,66 +556,74 @@
|
|
| 454 |
<small class="text-muted">Age: ${patient.age || 'N/A'} | Gender: ${patient.gender || 'N/A'}</small><br>
|
| 455 |
<small class="text-muted">Last Updated: ${patient.timestamp ? new Date(patient.timestamp).toLocaleString() : 'N/A'}</small>
|
| 456 |
</div>
|
| 457 |
-
<span class="patient-status ${statusBadgeClass[patient.status] || 'status-unknown'}"
|
|
|
|
|
|
|
|
|
|
| 458 |
</div>
|
| 459 |
-
<button class="delete-patient-btn" data-id="${patient.id}">
|
| 460 |
<i class="fas fa-trash-alt"></i>
|
| 461 |
</button>
|
| 462 |
</li>
|
| 463 |
`;
|
| 464 |
$('#patient-list').append(patientHtml);
|
| 465 |
});
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
// Add click event to patient items (excluding delete button clicks)
|
| 468 |
$('#patient-list').on('click', '.patient-item', function(event) {
|
| 469 |
// Check if the click target is the delete button or its icon
|
| 470 |
if ($(event.target).closest('.delete-patient-btn').length === 0) {
|
| 471 |
const patientId = $(this).data('id');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 472 |
// Update URL without full page reload
|
| 473 |
history.pushState({ patient_id: patientId }, '', `/doctor_dashboard?patient_id=${patientId}`);
|
| 474 |
loadPatientDetails(patientId);
|
| 475 |
}
|
| 476 |
});
|
| 477 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 478 |
|
| 479 |
// After loading the list, check if a patient ID is in the URL or if a patient was previously selected
|
| 480 |
const urlParams = new URLSearchParams(window.location.search);
|
| 481 |
const patientIdFromUrl = urlParams.get('patient_id');
|
| 482 |
|
| 483 |
-
|
| 484 |
-
|
|
|
|
|
|
|
|
|
|
| 485 |
// Check if this ID exists in the loaded list before trying to load details
|
| 486 |
-
if ($(`.patient-item[data-id="${
|
| 487 |
-
loadPatientDetails(
|
| 488 |
} else {
|
| 489 |
-
console.warn(`Patient ID "${
|
| 490 |
-
// Clear URL param if patient not found
|
| 491 |
history.replaceState({}, '', '/doctor_dashboard');
|
| 492 |
$('#no-patient-selected').show();
|
| 493 |
$('#patient-details-section').hide();
|
| 494 |
currentlySelectedPatientId = null; // Reset selected ID
|
|
|
|
|
|
|
| 495 |
}
|
| 496 |
-
} else
|
| 497 |
-
|
| 498 |
-
console.log("Checking for previously selected patient:", currentlySelectedPatientId);
|
| 499 |
-
if ($(`.patient-item[data-id="${currentlySelectedPatientId}"]`).length > 0) {
|
| 500 |
-
loadPatientDetails(currentlySelectedPatientId);
|
| 501 |
-
} else {
|
| 502 |
-
console.warn(`Previously selected patient ID "${currentlySelectedPatientId}" not found in loaded list.`);
|
| 503 |
-
history.replaceState({}, '', '/doctor_dashboard');
|
| 504 |
-
$('#no-patient-selected').show();
|
| 505 |
-
$('#patient-details-section').hide();
|
| 506 |
-
currentlySelectedPatientId = null; // Reset selected ID
|
| 507 |
-
}
|
| 508 |
-
|
| 509 |
-
}
|
| 510 |
-
else {
|
| 511 |
$('#no-patient-selected').show();
|
| 512 |
$('#patient-details-section').hide();
|
| 513 |
-
currentlySelectedPatientId = null; //
|
|
|
|
|
|
|
| 514 |
}
|
| 515 |
-
|
| 516 |
-
|
| 517 |
} else {
|
| 518 |
console.log("No patients found.");
|
| 519 |
$('#patient-count').text('0');
|
|
@@ -523,6 +633,8 @@
|
|
| 523 |
$('#no-patient-selected').show();
|
| 524 |
$('#patient-details-section').hide();
|
| 525 |
currentlySelectedPatientId = null; // Reset selected ID
|
|
|
|
|
|
|
| 526 |
}
|
| 527 |
},
|
| 528 |
error: function(xhr, status, error) {
|
|
@@ -535,15 +647,21 @@
|
|
| 535 |
$('#no-patient-selected').show();
|
| 536 |
$('#patient-details-section').hide();
|
| 537 |
currentlySelectedPatientId = null; // Reset selected ID
|
|
|
|
|
|
|
| 538 |
}
|
| 539 |
});
|
| 540 |
}
|
| 541 |
-
|
| 542 |
// Load patient details
|
| 543 |
function loadPatientDetails(patientId) {
|
| 544 |
console.log("Attempting to load details for patient ID:", patientId);
|
| 545 |
currentlySelectedPatientId = patientId; // Store the ID
|
| 546 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 547 |
// Highlight selected patient
|
| 548 |
$('.patient-item').removeClass('active');
|
| 549 |
$(`.patient-item[data-id="${patientId}"]`).addClass('active');
|
|
@@ -552,9 +670,16 @@
|
|
| 552 |
$('#no-patient-selected').hide();
|
| 553 |
$('#patient-details-section').show();
|
| 554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
// Optional: Show a loader in the details pane while fetching
|
| 556 |
// $('#patient-details-section .card-body').html('<div class="loader"></div>');
|
| 557 |
-
|
| 558 |
$.ajax({
|
| 559 |
url: `/get_patient/${patientId}`,
|
| 560 |
type: 'GET',
|
|
@@ -563,14 +688,12 @@
|
|
| 563 |
if (response.success) {
|
| 564 |
const patient = response.patient;
|
| 565 |
console.log("Successfully loaded patient details:", patient.name);
|
| 566 |
-
|
| 567 |
// Update patient details
|
| 568 |
$('#patient-name-header').html(`<i class="fas fa-user me-2"></i>${patient.name || 'Unnamed Patient'}`);
|
| 569 |
$('#patient-age').text(patient.age || 'N/A');
|
| 570 |
$('#patient-gender').text(patient.gender || 'N/A');
|
| 571 |
$('#patient-feedback').text(patient.feedback || 'No feedback recorded.');
|
| 572 |
$('#patient-timestamp').text(patient.timestamp ? new Date(patient.timestamp).toLocaleString() : 'N/A');
|
| 573 |
-
|
| 574 |
// Set status badge
|
| 575 |
const statusText = {
|
| 576 |
'emergency': 'EMERGENCY',
|
|
@@ -579,34 +702,37 @@
|
|
| 579 |
'stable': 'STABLE',
|
| 580 |
'unknown': 'UNKNOWN'
|
| 581 |
};
|
| 582 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 583 |
'emergency': 'status-emergency',
|
| 584 |
'deteriorating': 'status-deteriorating',
|
| 585 |
'improving': 'status-improving',
|
| 586 |
'stable': 'status-stable',
|
| 587 |
-
|
| 588 |
};
|
| 589 |
$('#patient-status')
|
| 590 |
-
.
|
| 591 |
-
.attr('class', 'patient-status ' + (statusBadgeClass[patient.status] || 'status-unknown'));
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
$
|
| 595 |
$('#original-plan-content').text(patient.original_plan || 'No original care plan available (or could not be extracted from PDF).');
|
| 596 |
-
|
| 597 |
// Reset tab to updated plan and show content
|
| 598 |
-
$
|
| 599 |
$('#updated-plan-tab').addClass('active').attr('aria-selected', 'true');
|
| 600 |
$('#carePlanTabsContent .tab-pane').removeClass('show active');
|
| 601 |
-
$('#updated-plan').addClass('show active');
|
| 602 |
-
|
| 603 |
-
|
| 604 |
-
// Set up PDF download button with patient ID
|
| 605 |
$('#download-pdf').off('click').on('click', function() {
|
| 606 |
console.log("Download button clicked for patient ID:", patient.id);
|
| 607 |
window.location.href = `/download_pdf/${patient.id}`;
|
| 608 |
});
|
| 609 |
-
|
| 610 |
} else {
|
| 611 |
console.error('Error loading patient details:', response.error);
|
| 612 |
alert('Error: ' + response.error);
|
|
@@ -615,6 +741,8 @@
|
|
| 615 |
$(`.patient-item[data-id="${patientId}"]`).removeClass('active'); // Remove highlight
|
| 616 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 617 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
|
|
|
|
|
|
| 618 |
}
|
| 619 |
},
|
| 620 |
error: function(xhr, status, error) {
|
|
@@ -625,99 +753,234 @@
|
|
| 625 |
$(`.patient-item[data-id="${patientId}"]`).removeClass('active'); // Remove highlight
|
| 626 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 627 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
|
|
|
|
|
|
| 628 |
}
|
| 629 |
});
|
| 630 |
}
|
| 631 |
|
| 632 |
-
//
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
// Optionally show a spinner or disable the delete button
|
| 644 |
-
const $deleteBtnIcon = $(this).find('i');
|
| 645 |
-
$deleteBtnIcon.removeClass().addClass('fas fa-spinner fa-spin');
|
| 646 |
-
$(this).prop('disabled', true);
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
$.ajax({
|
| 650 |
-
url: `/delete_patient/${patientIdToDelete}`,
|
| 651 |
-
type: 'DELETE',
|
| 652 |
-
success: function(response) {
|
| 653 |
-
console.log("Delete successful:", response.message);
|
| 654 |
-
// Remove the patient item from the list
|
| 655 |
-
$patientItem.remove();
|
| 656 |
-
// Update patient count
|
| 657 |
-
$('#patient-count').text($('#patient-list li').length);
|
| 658 |
-
// Check if the deleted patient was currently selected
|
| 659 |
-
if (currentlySelectedPatientId === patientIdToDelete) {
|
| 660 |
-
console.log("Deleted currently selected patient. Clearing details pane.");
|
| 661 |
-
$('#patient-details-section').hide();
|
| 662 |
-
$('#no-patient-selected').show();
|
| 663 |
-
currentlySelectedPatientId = null; // Reset selected ID
|
| 664 |
-
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
| 665 |
-
}
|
| 666 |
-
// Check if the list is now empty
|
| 667 |
-
if ($('#patient-list li').length === 0) {
|
| 668 |
-
$('#no-patients-found').show();
|
| 669 |
-
}
|
| 670 |
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
|
| 682 |
-
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
}
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 695 |
}
|
| 696 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 697 |
|
|
|
|
| 698 |
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 711 |
}
|
| 712 |
});
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 717 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 718 |
});
|
| 719 |
|
| 720 |
|
|
|
|
|
|
|
| 721 |
// Initial patient data load when page is ready
|
| 722 |
loadPatients();
|
| 723 |
|
|
@@ -728,29 +991,33 @@
|
|
| 728 |
url: '/get_emergency_notifications',
|
| 729 |
type: 'GET',
|
| 730 |
success: function(response) {
|
| 731 |
-
if (response.success
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
<div class="alert alert-danger mb-3">
|
| 738 |
<i class="fas fa-exclamation-triangle me-2"></i>
|
| 739 |
<strong>${alertCount} Emergency patient${alertCount > 1 ? 's' : ''} requiring immediate attention!</strong>
|
| 740 |
</div>
|
| 741 |
`;
|
| 742 |
-
|
| 743 |
-
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
}
|
| 749 |
-
|
| 750 |
} else {
|
| 751 |
-
|
| 752 |
-
|
| 753 |
-
|
| 754 |
}
|
| 755 |
},
|
| 756 |
error: function(xhr, status, error) {
|
|
@@ -760,22 +1027,26 @@
|
|
| 760 |
}
|
| 761 |
});
|
| 762 |
}
|
| 763 |
-
|
| 764 |
// Check for emergency notifications periodically (e.g., every 30 seconds)
|
| 765 |
setInterval(checkEmergencyNotifications, 30000); // 30 seconds
|
| 766 |
|
|
|
|
| 767 |
// Handle browser back/forward button for URL patient ID
|
| 768 |
window.onpopstate = function(event) {
|
| 769 |
const urlParams = new URLSearchParams(window.location.search);
|
| 770 |
const patientIdFromUrl = urlParams.get('patient_id');
|
| 771 |
-
|
| 772 |
// Compare with the ID of the patient currently *displayed* in the details pane
|
| 773 |
// This needs to be tracked separately as loadPatients might be async
|
| 774 |
-
const currentlyDisplayedPatientId = $('#patient-details-section').is(':visible') ? currentlySelectedPatientId : null;
|
| 775 |
-
|
| 776 |
|
| 777 |
-
if (patientIdFromUrl && patientIdFromUrl !==
|
| 778 |
console.log(`URL changed to patient ID: ${patientIdFromUrl}. Attempting to load details.`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 779 |
// Check if this ID exists in the currently rendered list before calling API
|
| 780 |
if ($(`.patient-item[data-id="${patientIdFromUrl}"]`).length > 0) {
|
| 781 |
loadPatientDetails(patientIdFromUrl);
|
|
@@ -786,15 +1057,27 @@
|
|
| 786 |
$('#no-patient-selected').show();
|
| 787 |
currentlySelectedPatientId = null; // Reset
|
| 788 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param if not found
|
|
|
|
|
|
|
| 789 |
}
|
| 790 |
-
} else if (!patientIdFromUrl &&
|
| 791 |
// If URL has no ID but a patient is currently displayed, hide details
|
| 792 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 793 |
$('.patient-item').removeClass('active'); // Remove highlight
|
| 794 |
$('#patient-details-section').hide();
|
| 795 |
$('#no-patient-selected').show();
|
| 796 |
currentlySelectedPatientId = null; // Reset
|
| 797 |
-
|
|
|
|
|
|
|
| 798 |
// If URL has the same ID as currently displayed, do nothing (user navigated back to the same state)
|
| 799 |
console.log("URL changed but same patient ID. No action needed.");
|
| 800 |
} else {
|
|
@@ -804,6 +1087,8 @@
|
|
| 804 |
$('#patient-details-section').hide();
|
| 805 |
$('#no-patient-selected').show();
|
| 806 |
currentlySelectedPatientId = null; // Reset
|
|
|
|
|
|
|
| 807 |
}
|
| 808 |
};
|
| 809 |
});
|
|
|
|
| 54 |
background-color: #2e59d9; /* Darker blue */
|
| 55 |
border-color: #2653d4;
|
| 56 |
}
|
| 57 |
+
.btn-success {
|
| 58 |
background-color: var(--secondary-color);
|
| 59 |
border-color: var(--secondary-color);
|
| 60 |
+
color: white; /* Ensure text is white */
|
| 61 |
+
}
|
| 62 |
+
.btn-success:hover {
|
| 63 |
+
background-color: #17a673; /* Darker green */
|
| 64 |
+
border-color: #159d6b;
|
| 65 |
}
|
| 66 |
.btn-danger {
|
| 67 |
background-color: var(--danger-color);
|
| 68 |
border-color: var(--danger-color);
|
| 69 |
}
|
| 70 |
+
.btn-warning {
|
| 71 |
+
background-color: var(--warning-color);
|
| 72 |
+
border-color: var(--warning-color);
|
| 73 |
+
color: #212529; /* Dark text for yellow */
|
| 74 |
+
}
|
| 75 |
+
.btn-warning:hover {
|
| 76 |
+
background-color: #f0ad4e; /* Darker yellow */
|
| 77 |
+
border-color: #ec971f;
|
| 78 |
+
}
|
| 79 |
.role-toggle {
|
| 80 |
display: flex;
|
| 81 |
align-items: center;
|
|
|
|
| 126 |
box-shadow: 0 0.3rem 0.8rem 0 rgba(58, 59, 69, 0.1);
|
| 127 |
background-color: #fcfcfc; /* Slightly lighter hover background */
|
| 128 |
}
|
|
|
|
| 129 |
.patient-item.active {
|
| 130 |
border: 1px solid var(--primary-color); /* Highlight active item */
|
| 131 |
border-left: 4px solid var(--primary-color);
|
|
|
|
| 146 |
.patient-item.unknown { /* Style for unknown status in list */
|
| 147 |
border-left-color: var(--dark-color);
|
| 148 |
}
|
|
|
|
| 149 |
.patient-status {
|
| 150 |
padding: 0.3rem 0.8rem; /* Slightly larger padding */
|
| 151 |
border-radius: 50rem;
|
|
|
|
| 176 |
margin-top: 1.5rem;
|
| 177 |
}
|
| 178 |
.care-plan-content {
|
| 179 |
+
background-color: white; /* Changed background */
|
| 180 |
border-radius: 0 0 0.35rem 0.35rem; /* Rounded corners at bottom */
|
| 181 |
border: 1px solid var(--border-color);
|
| 182 |
border-top: none; /* No border top because of tabs */
|
|
|
|
| 189 |
font-size: 1rem;
|
| 190 |
color: #333;
|
| 191 |
}
|
| 192 |
+
#updated-plan-content-edit {
|
| 193 |
+
width: 100%;
|
| 194 |
+
height: 400px; /* Match display height */
|
| 195 |
+
padding: 1.5rem;
|
| 196 |
+
border: 1px solid var(--border-color);
|
| 197 |
+
border-top: none;
|
| 198 |
+
border-radius: 0 0 0.35rem 0.35rem;
|
| 199 |
+
font-size: 1rem;
|
| 200 |
+
color: #333;
|
| 201 |
+
resize: vertical; /* Allow vertical resize */
|
| 202 |
+
display: none; /* Hidden by default */
|
| 203 |
+
}
|
| 204 |
.patient-details-section {
|
| 205 |
display: none; /* Hidden by default */
|
| 206 |
}
|
|
|
|
| 237 |
#patient-feedback {
|
| 238 |
background-color: #e9ecef; /* Light grey */
|
| 239 |
border-color: #dee2e6; /* Light grey border */
|
| 240 |
+
padding: 1rem; /* Added padding */
|
| 241 |
+
border-radius: 0.25rem; /* Rounded corners */
|
| 242 |
+
white-space: pre-line; /* Preserve line breaks */
|
| 243 |
+
word-wrap: break-word; /* Prevent overflow */
|
| 244 |
}
|
| 245 |
/* Delete button styling */
|
| 246 |
.delete-patient-btn {
|
|
|
|
| 268 |
.patient-item > div:first-child {
|
| 269 |
margin-right: 2rem; /* Add margin to the content to make space for the button */
|
| 270 |
}
|
| 271 |
+
.btn-spinner {
|
| 272 |
+
display: inline-block;
|
| 273 |
+
width: 1rem;
|
| 274 |
+
height: 1rem;
|
| 275 |
+
vertical-align: middle;
|
| 276 |
+
border-radius: 50%;
|
| 277 |
+
border: 0.15em solid currentColor;
|
| 278 |
+
border-right-color: transparent;
|
| 279 |
+
animation: .75s linear infinite spinner-border;
|
| 280 |
+
}
|
| 281 |
+
@keyframes spinner-border {
|
| 282 |
+
to { transform: rotate(360deg); }
|
| 283 |
+
}
|
| 284 |
+
.d-flex.align-items-center > .btn-spinner {
|
| 285 |
+
margin-left: 0.5rem;
|
| 286 |
+
}
|
| 287 |
+
.status-dot {
|
| 288 |
+
display: inline-block;
|
| 289 |
+
width: 10px;
|
| 290 |
+
height: 10px;
|
| 291 |
+
border-radius: 50%;
|
| 292 |
+
margin-right: 5px;
|
| 293 |
+
vertical-align: middle;
|
| 294 |
+
}
|
| 295 |
+
.status-dot.emergency { background-color: var(--danger-color); }
|
| 296 |
+
.status-dot.deteriorating { background-color: var(--warning-color); }
|
| 297 |
+
.status-dot.improving { background-color: var(--secondary-color); }
|
| 298 |
+
.status-dot.stable { background-color: var(--info-color); }
|
| 299 |
+
.status-dot.unknown { background-color: var(--dark-color); }
|
| 300 |
+
|
| 301 |
</style>
|
| 302 |
</head>
|
| 303 |
<body>
|
|
|
|
| 318 |
</li>
|
| 319 |
<li class="nav-item">
|
| 320 |
<div class="role-toggle">
|
| 321 |
+
<!-- Using forms for role switching -->
|
| 322 |
+
<form id="switch-to-patient-form" action="/switch_role" method="post" class="d-inline-block me-2">
|
| 323 |
+
<input type="hidden" name="role" value="patient">
|
| 324 |
+
<button type="submit" class="role-toggle-btn">
|
| 325 |
+
<i class="fas fa-user"></i> Patient
|
| 326 |
+
</button>
|
| 327 |
+
</form>
|
| 328 |
+
<form id="switch-to-doctor-form" action="/switch_role" method="post" class="d-inline-block">
|
| 329 |
+
<input type="hidden" name="role" value="doctor">
|
| 330 |
+
<button type="submit" class="role-toggle-btn active">
|
| 331 |
+
<i class="fas fa-user-md"></i> Doctor
|
| 332 |
+
</button>
|
| 333 |
+
</form>
|
| 334 |
</div>
|
| 335 |
</li>
|
| 336 |
</ul>
|
|
|
|
| 393 |
<p id="patient-feedback" class="p-3 bg-light rounded border"></p>
|
| 394 |
</div>
|
| 395 |
|
| 396 |
+
<div class="mb-3">
|
| 397 |
<strong>Last Updated:</strong> <span id="patient-timestamp"></span>
|
| 398 |
+
</div>
|
| 399 |
+
|
| 400 |
+
<!-- Action Buttons -->
|
| 401 |
+
<div class="d-flex gap-2 mb-4">
|
| 402 |
+
<button class="btn btn-primary d-flex align-items-center" id="download-pdf">
|
| 403 |
+
<i class="fas fa-file-download me-2"></i>Download Care Plan PDF
|
| 404 |
+
</button>
|
| 405 |
+
<!-- WhatsApp button - initially hidden until patient selected -->
|
| 406 |
+
<button class="btn btn-success d-flex align-items-center" id="send-whatsapp-btn" style="display: none;">
|
| 407 |
+
<i class="fab fa-whatsapp me-2"></i>Send via WhatsApp
|
| 408 |
+
</button>
|
| 409 |
+
<!-- Loader/Feedback for WhatsApp send -->
|
| 410 |
+
<div id="whatsapp-feedback" class="ms-3 align-self-center"></div>
|
| 411 |
+
</div>
|
| 412 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
|
| 414 |
<div class="care-plan-tabs mt-4">
|
| 415 |
<ul class="nav nav-tabs" id="carePlanTabs" role="tablist">
|
| 416 |
<li class="nav-item" role="presentation">
|
| 417 |
+
<button class="nav-link active" id="updated-plan-tab" data-bs-toggle="tab" data-bs-target="#updated-plan-container" type="button" role="tab" aria-controls="updated-plan-container" aria-selected="true">Updated Care Plan</button>
|
| 418 |
</li>
|
| 419 |
<li class="nav-item" role="presentation">
|
| 420 |
<button class="nav-link" id="original-plan-tab" data-bs-toggle="tab" data-bs-target="#original-plan" type="button" role="tab" aria-controls="original-plan" aria-selected="false">Original Care Plan</button>
|
| 421 |
</li>
|
| 422 |
</ul>
|
| 423 |
<div class="tab-content" id="carePlanTabsContent">
|
| 424 |
+
<!-- Updated Plan Container -->
|
| 425 |
+
<div class="tab-pane fade show active" id="updated-plan-container" role="tabpanel" aria-labelledby="updated-plan-tab">
|
| 426 |
+
<div class="d-flex justify-content-end align-items-center mt-3 me-3" id="edit-save-buttons">
|
| 427 |
+
<button class="btn btn-sm btn-warning me-2" id="edit-plan-btn">
|
| 428 |
+
<i class="fas fa-edit me-1"></i> Edit
|
| 429 |
+
</button>
|
| 430 |
+
<button class="btn btn-sm btn-success me-2" id="save-plan-btn" style="display: none;">
|
| 431 |
+
<i class="fas fa-save me-1"></i> Save
|
| 432 |
+
</button>
|
| 433 |
+
<button class="btn btn-sm btn-secondary" id="cancel-plan-btn" style="display: none;">
|
| 434 |
+
<i class="fas fa-times me-1"></i> Cancel
|
| 435 |
+
</button>
|
| 436 |
+
<div id="save-feedback" class="ms-2 small"></div>
|
| 437 |
+
</div>
|
| 438 |
+
|
| 439 |
+
<!-- Display area -->
|
| 440 |
+
<div class="care-plan-content" id="updated-plan-content-display"></div>
|
| 441 |
+
<!-- Edit area (textarea) -->
|
| 442 |
+
<textarea class="form-control" id="updated-plan-content-edit" style="display: none;"></textarea>
|
| 443 |
</div>
|
| 444 |
+
|
| 445 |
+
<!-- Original Plan Tab -->
|
| 446 |
<div class="tab-pane fade" id="original-plan" role="tabpanel" aria-labelledby="original-plan-tab">
|
| 447 |
<div class="care-plan-content" id="original-plan-content"></div>
|
| 448 |
</div>
|
|
|
|
| 464 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
| 465 |
<script>
|
| 466 |
$(document).ready(function() {
|
| 467 |
+
// Set active role button on load (handled by forms now)
|
| 468 |
+
// $('.role-toggle-btn[data-role="doctor"]').addClass('active');
|
| 469 |
+
// $('.role-toggle-btn[data-role="patient"]').removeClass('active');
|
| 470 |
|
| 471 |
// Placeholder for storing selected patient ID
|
| 472 |
let currentlySelectedPatientId = null;
|
| 473 |
+
let isEditingPlan = false; // State variable for edit mode
|
| 474 |
+
|
| 475 |
+
// Elements for Updated Plan editing
|
| 476 |
+
const $updatedPlanDisplay = $('#updated-plan-content-display');
|
| 477 |
+
const $updatedPlanEdit = $('#updated-plan-content-edit');
|
| 478 |
+
const $editBtn = $('#edit-plan-btn');
|
| 479 |
+
const $saveBtn = $('#save-plan-btn');
|
| 480 |
+
const $cancelBtn = $('#cancel-plan-btn');
|
| 481 |
+
const $saveFeedback = $('#save-feedback');
|
| 482 |
+
const $whatsappBtn = $('#send-whatsapp-btn');
|
| 483 |
+
const $whatsappFeedback = $('#whatsapp-feedback');
|
| 484 |
+
const $carePlanTabs = $('#carePlanTabs button'); // All tab buttons
|
| 485 |
+
|
| 486 |
|
| 487 |
// Load all patients
|
| 488 |
function loadPatients() {
|
|
|
|
| 491 |
$('#no-patients-found').hide();
|
| 492 |
$('#patient-list-error').hide(); // Hide previous error
|
| 493 |
$('#patient-list').empty(); // Clear current list
|
|
|
|
| 494 |
$.ajax({
|
| 495 |
url: '/get_patients',
|
| 496 |
type: 'GET',
|
|
|
|
| 500 |
console.log("Patients loaded:", response.patients.length);
|
| 501 |
// Update patient count
|
| 502 |
$('#patient-count').text(response.patients.length);
|
|
|
|
| 503 |
// Sort patients by status priority (Emergency first) then timestamp (newest first)
|
| 504 |
const statusPriority = { 'emergency': 0, 'deteriorating': 1, 'improving': 2, 'stable': 3, 'unknown': 4 };
|
| 505 |
const sortedPatients = response.patients.sort((a, b) => {
|
|
|
|
| 512 |
const dateB = new Date(b.timestamp || '1900-01-01T00:00:00Z'); // Handle missing timestamp
|
| 513 |
return dateB - dateA; // Newest first
|
| 514 |
});
|
|
|
|
| 515 |
// Populate emergency alerts
|
| 516 |
const emergencyPatients = sortedPatients.filter(p => p.status === 'emergency');
|
| 517 |
if (emergencyPatients.length > 0) {
|
|
|
|
| 525 |
} else {
|
| 526 |
$('#emergency-alerts').empty();
|
| 527 |
}
|
|
|
|
| 528 |
// Populate patient list
|
| 529 |
sortedPatients.forEach(patient => {
|
| 530 |
const statusText = {
|
|
|
|
| 556 |
<small class="text-muted">Age: ${patient.age || 'N/A'} | Gender: ${patient.gender || 'N/A'}</small><br>
|
| 557 |
<small class="text-muted">Last Updated: ${patient.timestamp ? new Date(patient.timestamp).toLocaleString() : 'N/A'}</small>
|
| 558 |
</div>
|
| 559 |
+
<span class="patient-status ${statusBadgeClass[patient.status] || 'status-unknown'}">
|
| 560 |
+
<span class="status-dot ${statusClass[patient.status] || 'unknown'}"></span>
|
| 561 |
+
${statusText[patient.status] || 'UNKNOWN'}
|
| 562 |
+
</span>
|
| 563 |
</div>
|
| 564 |
+
<button class="delete-patient-btn" data-id="${patient.id}" title="Delete Patient Record">
|
| 565 |
<i class="fas fa-trash-alt"></i>
|
| 566 |
</button>
|
| 567 |
</li>
|
| 568 |
`;
|
| 569 |
$('#patient-list').append(patientHtml);
|
| 570 |
});
|
| 571 |
+
// Remove previous event handlers before adding new ones
|
| 572 |
+
$('#patient-list').off('click', '.patient-item');
|
| 573 |
+
$('#patient-list').off('click', '.delete-patient-btn');
|
| 574 |
|
| 575 |
// Add click event to patient items (excluding delete button clicks)
|
| 576 |
$('#patient-list').on('click', '.patient-item', function(event) {
|
| 577 |
// Check if the click target is the delete button or its icon
|
| 578 |
if ($(event.target).closest('.delete-patient-btn').length === 0) {
|
| 579 |
const patientId = $(this).data('id');
|
| 580 |
+
// Check if currently editing before switching
|
| 581 |
+
if (isEditingPlan && currentlySelectedPatientId !== patientId) {
|
| 582 |
+
if (!confirm("You have unsaved changes. Discard changes and switch patients?")) {
|
| 583 |
+
return; // Do not switch if user cancels
|
| 584 |
+
}
|
| 585 |
+
}
|
| 586 |
// Update URL without full page reload
|
| 587 |
history.pushState({ patient_id: patientId }, '', `/doctor_dashboard?patient_id=${patientId}`);
|
| 588 |
loadPatientDetails(patientId);
|
| 589 |
}
|
| 590 |
});
|
| 591 |
+
// Add click event for deletion (delegated)
|
| 592 |
+
$('#patient-list').on('click', '.delete-patient-btn', function(event) {
|
| 593 |
+
// This handler is separate and will only fire for the delete button
|
| 594 |
+
handleDeletePatient($(this).data('id'));
|
| 595 |
+
});
|
| 596 |
|
| 597 |
// After loading the list, check if a patient ID is in the URL or if a patient was previously selected
|
| 598 |
const urlParams = new URLSearchParams(window.location.search);
|
| 599 |
const patientIdFromUrl = urlParams.get('patient_id');
|
| 600 |
|
| 601 |
+
// Determine which patient ID to try loading initially
|
| 602 |
+
let idToLoad = patientIdFromUrl || currentlySelectedPatientId;
|
| 603 |
+
|
| 604 |
+
if (idToLoad) {
|
| 605 |
+
console.log("Checking for patient from URL or previously selected:", idToLoad);
|
| 606 |
// Check if this ID exists in the loaded list before trying to load details
|
| 607 |
+
if ($(`.patient-item[data-id="${idToLoad}"]`).length > 0) {
|
| 608 |
+
loadPatientDetails(idToLoad);
|
| 609 |
} else {
|
| 610 |
+
console.warn(`Patient ID "${idToLoad}" from URL/previous not found in loaded list.`);
|
| 611 |
+
// Clear URL param and reset if patient not found
|
| 612 |
history.replaceState({}, '', '/doctor_dashboard');
|
| 613 |
$('#no-patient-selected').show();
|
| 614 |
$('#patient-details-section').hide();
|
| 615 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 616 |
+
resetCarePlanEditState(); // Reset edit state
|
| 617 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 618 |
}
|
| 619 |
+
} else {
|
| 620 |
+
console.log("No patient ID in URL or previously selected. Showing placeholder.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 621 |
$('#no-patient-selected').show();
|
| 622 |
$('#patient-details-section').hide();
|
| 623 |
+
currentlySelectedPatientId = null; // Reset selected ID
|
| 624 |
+
resetCarePlanEditState(); // Reset edit state
|
| 625 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 626 |
}
|
|
|
|
|
|
|
| 627 |
} else {
|
| 628 |
console.log("No patients found.");
|
| 629 |
$('#patient-count').text('0');
|
|
|
|
| 633 |
$('#no-patient-selected').show();
|
| 634 |
$('#patient-details-section').hide();
|
| 635 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 636 |
+
resetCarePlanEditState(); // Reset edit state
|
| 637 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 638 |
}
|
| 639 |
},
|
| 640 |
error: function(xhr, status, error) {
|
|
|
|
| 647 |
$('#no-patient-selected').show();
|
| 648 |
$('#patient-details-section').hide();
|
| 649 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 650 |
+
resetCarePlanEditState(); // Reset edit state
|
| 651 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 652 |
}
|
| 653 |
});
|
| 654 |
}
|
|
|
|
| 655 |
// Load patient details
|
| 656 |
function loadPatientDetails(patientId) {
|
| 657 |
console.log("Attempting to load details for patient ID:", patientId);
|
| 658 |
currentlySelectedPatientId = patientId; // Store the ID
|
| 659 |
|
| 660 |
+
// Reset any previous editing state and feedback messages
|
| 661 |
+
resetCarePlanEditState();
|
| 662 |
+
$saveFeedback.empty();
|
| 663 |
+
$whatsappFeedback.empty();
|
| 664 |
+
|
| 665 |
// Highlight selected patient
|
| 666 |
$('.patient-item').removeClass('active');
|
| 667 |
$(`.patient-item[data-id="${patientId}"]`).addClass('active');
|
|
|
|
| 670 |
$('#no-patient-selected').hide();
|
| 671 |
$('#patient-details-section').show();
|
| 672 |
|
| 673 |
+
// Show WhatsApp button for the selected patient
|
| 674 |
+
$whatsappBtn.show();
|
| 675 |
+
// Set up WhatsApp button click handler for the selected patient
|
| 676 |
+
$whatsappBtn.off('click').on('click', function() {
|
| 677 |
+
handleSendWhatsApp(currentlySelectedPatientId);
|
| 678 |
+
});
|
| 679 |
+
|
| 680 |
+
|
| 681 |
// Optional: Show a loader in the details pane while fetching
|
| 682 |
// $('#patient-details-section .card-body').html('<div class="loader"></div>');
|
|
|
|
| 683 |
$.ajax({
|
| 684 |
url: `/get_patient/${patientId}`,
|
| 685 |
type: 'GET',
|
|
|
|
| 688 |
if (response.success) {
|
| 689 |
const patient = response.patient;
|
| 690 |
console.log("Successfully loaded patient details:", patient.name);
|
|
|
|
| 691 |
// Update patient details
|
| 692 |
$('#patient-name-header').html(`<i class="fas fa-user me-2"></i>${patient.name || 'Unnamed Patient'}`);
|
| 693 |
$('#patient-age').text(patient.age || 'N/A');
|
| 694 |
$('#patient-gender').text(patient.gender || 'N/A');
|
| 695 |
$('#patient-feedback').text(patient.feedback || 'No feedback recorded.');
|
| 696 |
$('#patient-timestamp').text(patient.timestamp ? new Date(patient.timestamp).toLocaleString() : 'N/A');
|
|
|
|
| 697 |
// Set status badge
|
| 698 |
const statusText = {
|
| 699 |
'emergency': 'EMERGENCY',
|
|
|
|
| 702 |
'stable': 'STABLE',
|
| 703 |
'unknown': 'UNKNOWN'
|
| 704 |
};
|
| 705 |
+
const statusClass = {
|
| 706 |
+
'emergency': 'emergency',
|
| 707 |
+
'deteriorating': 'deteriorating',
|
| 708 |
+
'improving': 'improving',
|
| 709 |
+
'stable': 'stable',
|
| 710 |
+
'unknown': 'unknown'
|
| 711 |
+
};
|
| 712 |
+
const statusBadgeClass = {
|
| 713 |
'emergency': 'status-emergency',
|
| 714 |
'deteriorating': 'status-deteriorating',
|
| 715 |
'improving': 'status-improving',
|
| 716 |
'stable': 'status-stable',
|
| 717 |
+
'unknown': 'status-unknown'
|
| 718 |
};
|
| 719 |
$('#patient-status')
|
| 720 |
+
.html(`<span class="status-dot ${statusClass[patient.status] || 'unknown'}"></span>${statusText[patient.status] || 'UNKNOWN'}`) // Include dot in HTML
|
| 721 |
+
.attr('class', 'patient-status ' + (statusBadgeClass[patient.status] || 'status-unknown')); // Set class for background
|
| 722 |
+
// Update care plans content - populate both display div and edit textarea
|
| 723 |
+
$updatedPlanDisplay.text(patient.updated_plan || 'No updated care plan available.');
|
| 724 |
+
$updatedPlanEdit.val(patient.updated_plan || 'No updated care plan available.'); // Use .val() for textarea
|
| 725 |
$('#original-plan-content').text(patient.original_plan || 'No original care plan available (or could not be extracted from PDF).');
|
|
|
|
| 726 |
// Reset tab to updated plan and show content
|
| 727 |
+
$carePlanTabs.removeClass('active').attr('aria-selected', 'false');
|
| 728 |
$('#updated-plan-tab').addClass('active').attr('aria-selected', 'true');
|
| 729 |
$('#carePlanTabsContent .tab-pane').removeClass('show active');
|
| 730 |
+
$('#updated-plan-container').addClass('show active');
|
| 731 |
+
// Set up PDF download button click handler for the selected patient
|
|
|
|
|
|
|
| 732 |
$('#download-pdf').off('click').on('click', function() {
|
| 733 |
console.log("Download button clicked for patient ID:", patient.id);
|
| 734 |
window.location.href = `/download_pdf/${patient.id}`;
|
| 735 |
});
|
|
|
|
| 736 |
} else {
|
| 737 |
console.error('Error loading patient details:', response.error);
|
| 738 |
alert('Error: ' + response.error);
|
|
|
|
| 741 |
$(`.patient-item[data-id="${patientId}"]`).removeClass('active'); // Remove highlight
|
| 742 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 743 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
| 744 |
+
resetCarePlanEditState(); // Reset edit state
|
| 745 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 746 |
}
|
| 747 |
},
|
| 748 |
error: function(xhr, status, error) {
|
|
|
|
| 753 |
$(`.patient-item[data-id="${patientId}"]`).removeClass('active'); // Remove highlight
|
| 754 |
currentlySelectedPatientId = null; // Reset selected ID
|
| 755 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
| 756 |
+
resetCarePlanEditState(); // Reset edit state
|
| 757 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 758 |
}
|
| 759 |
});
|
| 760 |
}
|
| 761 |
|
| 762 |
+
// Reset the care plan editing state
|
| 763 |
+
function resetCarePlanEditState() {
|
| 764 |
+
isEditingPlan = false;
|
| 765 |
+
$updatedPlanDisplay.show();
|
| 766 |
+
$updatedPlanEdit.hide();
|
| 767 |
+
$editBtn.show();
|
| 768 |
+
$saveBtn.hide();
|
| 769 |
+
$cancelBtn.hide();
|
| 770 |
+
$saveFeedback.empty();
|
| 771 |
+
$carePlanTabs.prop('disabled', false); // Enable tabs
|
| 772 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 773 |
|
| 774 |
+
// Handle Delete Patient Action
|
| 775 |
+
function handleDeletePatient(patientIdToDelete) {
|
| 776 |
+
const $patientItem = $(`.patient-item[data-id="${patientIdToDelete}"]`);
|
| 777 |
+
const patientName = $patientItem.find('h6').text() || 'Unnamed Patient';
|
| 778 |
+
if (confirm(`Are you sure you want to delete the record for ${patientName}? This action cannot be undone.`)) {
|
| 779 |
+
console.log(`Deleting patient ID: ${patientIdToDelete}`);
|
| 780 |
+
// Optionally show a spinner or disable the delete button
|
| 781 |
+
const $deleteBtnIcon = $patientItem.find('.delete-patient-btn i');
|
| 782 |
+
const originalIconClass = $deleteBtnIcon.attr('class');
|
| 783 |
+
$deleteBtnIcon.removeClass().addClass('fas fa-spinner fa-spin');
|
| 784 |
+
$patientItem.find('.delete-patient-btn').prop('disabled', true);
|
| 785 |
+
|
| 786 |
+
$.ajax({
|
| 787 |
+
url: `/delete_patient/${patientIdToDelete}`,
|
| 788 |
+
type: 'DELETE',
|
| 789 |
+
success: function(response) {
|
| 790 |
+
console.log("Delete successful:", response.message);
|
| 791 |
+
// Remove the patient item from the list
|
| 792 |
+
$patientItem.remove();
|
| 793 |
+
// Update patient count
|
| 794 |
+
$('#patient-count').text($('#patient-list li:visible').length); // Count visible items
|
| 795 |
+
// Check if the deleted patient was currently selected
|
| 796 |
+
if (currentlySelectedPatientId === patientIdToDelete) {
|
| 797 |
+
console.log("Deleted currently selected patient. Clearing details pane.");
|
| 798 |
+
$('#patient-details-section').hide();
|
| 799 |
+
$('#no-patient-selected').show();
|
| 800 |
+
currentlySelectedPatientId = null; // Reset selected ID
|
| 801 |
+
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param
|
| 802 |
+
resetCarePlanEditState(); // Reset edit state
|
| 803 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 804 |
}
|
| 805 |
+
// Check if the list is now empty (considering only visible items after search)
|
| 806 |
+
if ($('#patient-list li:visible').length === 0) {
|
| 807 |
+
$('#no-patients-found').show();
|
| 808 |
+
}
|
| 809 |
+
// Reload the full patient list could also be an option here
|
| 810 |
+
// instead of just removing the element, to ensure sorting/alerts are updated
|
| 811 |
+
// loadPatients();
|
| 812 |
+
},
|
| 813 |
+
error: function(xhr, status, error) {
|
| 814 |
+
console.error("Delete failed:", error, xhr.responseText);
|
| 815 |
+
// Re-enable button and restore icon on error
|
| 816 |
+
$deleteBtnIcon.removeClass().addClass(originalIconClass);
|
| 817 |
+
$patientItem.find('.delete-patient-btn').prop('disabled', false);
|
| 818 |
+
let errorMessage = 'An error occurred during deletion.';
|
| 819 |
+
if (xhr.responseJSON && xhr.responseJSON.error) {
|
| 820 |
+
errorMessage = xhr.responseJSON.error;
|
| 821 |
+
} else if (xhr.responseText) {
|
| 822 |
+
errorMessage += ": " + xhr.responseText.substring(0, 100) + "..."; // Avoid long error messages
|
| 823 |
+
} else {
|
| 824 |
+
errorMessage += ": " + error;
|
| 825 |
+
}
|
| 826 |
+
alert(`Error deleting patient: ${errorMessage}`);
|
| 827 |
+
}
|
| 828 |
+
});
|
| 829 |
+
} else {
|
| 830 |
+
console.log("Delete cancelled.");
|
| 831 |
+
}
|
| 832 |
+
}
|
| 833 |
+
|
| 834 |
+
|
| 835 |
+
// Handle Save Care Plan Action
|
| 836 |
+
function handleSaveCarePlan() {
|
| 837 |
+
if (!currentlySelectedPatientId) {
|
| 838 |
+
console.error("No patient selected for saving.");
|
| 839 |
+
$saveFeedback.html('<span class="text-danger">Error: No patient selected.</span>');
|
| 840 |
+
return;
|
| 841 |
}
|
| 842 |
+
const updatedPlanText = $updatedPlanEdit.val();
|
| 843 |
+
|
| 844 |
+
// Show spinner and disable buttons
|
| 845 |
+
$saveBtn.prop('disabled', true).html('<span class="btn-spinner"></span> Saving...');
|
| 846 |
+
$cancelBtn.prop('disabled', true);
|
| 847 |
+
$editBtn.prop('disabled', true); // Should already be hidden but good practice
|
| 848 |
+
$saveFeedback.empty(); // Clear previous feedback
|
| 849 |
|
| 850 |
+
console.log(`Saving plan for patient ID: ${currentlySelectedPatientId}`);
|
| 851 |
|
| 852 |
+
$.ajax({
|
| 853 |
+
url: `/update_care_plan/${currentlySelectedPatientId}`,
|
| 854 |
+
type: 'PUT',
|
| 855 |
+
contentType: 'application/json', // Specify content type
|
| 856 |
+
data: JSON.stringify({ updated_plan: updatedPlanText }), // Send as JSON
|
| 857 |
+
success: function(response) {
|
| 858 |
+
console.log("Save successful:", response.message);
|
| 859 |
+
$saveFeedback.html('<span class="text-success"><i class="fas fa-check-circle"></i> Saved!</span>');
|
| 860 |
+
|
| 861 |
+
// Update the display div with the saved text
|
| 862 |
+
$updatedPlanDisplay.text(updatedPlanText);
|
| 863 |
+
|
| 864 |
+
// Revert back to display mode
|
| 865 |
+
resetCarePlanEditState();
|
| 866 |
+
// Re-enable buttons and restore text after a short delay for feedback visibility
|
| 867 |
+
setTimeout(function() {
|
| 868 |
+
$saveBtn.prop('disabled', false).html('<i class="fas fa-save me-1"></i> Save');
|
| 869 |
+
$cancelBtn.prop('disabled', false);
|
| 870 |
+
$editBtn.prop('disabled', false); // Should be visible now
|
| 871 |
+
$saveFeedback.empty(); // Clear success message
|
| 872 |
+
}, 2000);
|
| 873 |
+
|
| 874 |
+
|
| 875 |
+
},
|
| 876 |
+
error: function(xhr, status, error) {
|
| 877 |
+
console.error("Save failed:", error, xhr.responseText);
|
| 878 |
+
let errorMessage = 'An error occurred while saving.';
|
| 879 |
+
if (xhr.responseJSON && xhr.responseJSON.error) {
|
| 880 |
+
errorMessage = xhr.responseJSON.error;
|
| 881 |
+
} else if (xhr.responseText) {
|
| 882 |
+
errorMessage += ": " + xhr.responseText.substring(0, 100) + "..."; // Avoid long error messages
|
| 883 |
+
} else {
|
| 884 |
+
errorMessage += ": " + error;
|
| 885 |
+
}
|
| 886 |
+
$saveFeedback.html(`<span class="text-danger"><i class="fas fa-exclamation-circle"></i> ${errorMessage}</span>`);
|
| 887 |
+
// Re-enable buttons
|
| 888 |
+
$saveBtn.prop('disabled', false).html('<i class="fas fa-save me-1"></i> Save');
|
| 889 |
+
$cancelBtn.prop('disabled', false);
|
| 890 |
+
$editBtn.prop('disabled', false); // Should already be hidden
|
| 891 |
}
|
| 892 |
});
|
| 893 |
+
}
|
| 894 |
+
|
| 895 |
+
|
| 896 |
+
// Handle Send WhatsApp Action
|
| 897 |
+
function handleSendWhatsApp(patientIdToSend) {
|
| 898 |
+
if (!patientIdToSend) {
|
| 899 |
+
console.error("No patient selected for sending WhatsApp.");
|
| 900 |
+
$whatsappFeedback.html('<span class="text-danger">Error: No patient selected.</span>');
|
| 901 |
+
return;
|
| 902 |
+
}
|
| 903 |
+
|
| 904 |
+
// Prevent sending if currently editing
|
| 905 |
+
if (isEditingPlan) {
|
| 906 |
+
$whatsappFeedback.html('<span class="text-danger">Finish editing before sending.</span>');
|
| 907 |
+
return;
|
| 908 |
+
}
|
| 909 |
+
|
| 910 |
+
// Show spinner and disable button
|
| 911 |
+
$whatsappBtn.prop('disabled', true).html('<span class="btn-spinner"></span> Sending...');
|
| 912 |
+
$whatsappFeedback.empty(); // Clear previous feedback
|
| 913 |
+
|
| 914 |
+
console.log(`Sending WhatsApp for patient ID: ${patientIdToSend}`);
|
| 915 |
+
|
| 916 |
+
$.ajax({
|
| 917 |
+
url: `/send_whatsapp_doctor/${patientIdToSend}`,
|
| 918 |
+
type: 'POST',
|
| 919 |
+
success: function(response) {
|
| 920 |
+
console.log("WhatsApp send successful:", response.message);
|
| 921 |
+
$whatsappFeedback.html('<span class="text-success"><i class="fab fa-whatsapp"></i> Sent!</span>');
|
| 922 |
+
// Re-enable button and restore text after a short delay for feedback visibility
|
| 923 |
+
setTimeout(function() {
|
| 924 |
+
$whatsappBtn.prop('disabled', false).html('<i class="fab fa-whatsapp me-2"></i>Send via WhatsApp');
|
| 925 |
+
$whatsappFeedback.empty();
|
| 926 |
+
}, 3000); // Show success for 3 seconds
|
| 927 |
+
},
|
| 928 |
+
error: function(xhr, status, error) {
|
| 929 |
+
console.error("WhatsApp send failed:", error, xhr.responseText);
|
| 930 |
+
let errorMessage = 'An error occurred while sending WhatsApp.';
|
| 931 |
+
if (xhr.responseJSON && xhr.responseJSON.error) {
|
| 932 |
+
errorMessage = xhr.responseJSON.error;
|
| 933 |
+
} else if (xhr.responseText) {
|
| 934 |
+
errorMessage += ": " + xhr.responseText.substring(0, 100) + "..."; // Avoid long error messages
|
| 935 |
+
} else {
|
| 936 |
+
errorMessage += ": " + error;
|
| 937 |
+
}
|
| 938 |
+
$whatsappFeedback.html(`<span class="text-danger"><i class="fas fa-exclamation-circle"></i> ${errorMessage}</span>`);
|
| 939 |
+
// Re-enable button immediately
|
| 940 |
+
$whatsappBtn.prop('disabled', false).html('<i class="fab fa-whatsapp me-2"></i>Send via WhatsApp');
|
| 941 |
+
}
|
| 942 |
+
});
|
| 943 |
+
}
|
| 944 |
+
|
| 945 |
+
|
| 946 |
+
// --- Event Listeners for Edit/Save/Cancel ---
|
| 947 |
+
|
| 948 |
+
$editBtn.on('click', function() {
|
| 949 |
+
if (!currentlySelectedPatientId) return; // Do nothing if no patient is selected
|
| 950 |
+
|
| 951 |
+
isEditingPlan = true;
|
| 952 |
+
$updatedPlanDisplay.hide(); // Hide display div
|
| 953 |
+
$updatedPlanEdit.show(); // Show textarea
|
| 954 |
+
$editBtn.hide(); // Hide edit button
|
| 955 |
+
$saveBtn.show(); // Show save button
|
| 956 |
+
$cancelBtn.show(); // Show cancel button
|
| 957 |
+
$saveFeedback.empty(); // Clear any previous feedback
|
| 958 |
+
$whatsappFeedback.empty(); // Clear whatsapp feedback as well
|
| 959 |
+
|
| 960 |
+
// Prevent switching tabs while editing
|
| 961 |
+
$carePlanTabs.prop('disabled', true);
|
| 962 |
+
$('#updated-plan-tab').prop('disabled', false); // Keep current tab enabled
|
| 963 |
+
});
|
| 964 |
+
|
| 965 |
+
$cancelBtn.on('click', function() {
|
| 966 |
+
if (isEditingPlan && confirm("Discard changes?")) {
|
| 967 |
+
// Revert textarea content to the text in the display div (original state before edit)
|
| 968 |
+
$updatedPlanEdit.val($updatedPlanDisplay.text());
|
| 969 |
+
resetCarePlanEditState(); // Revert UI state
|
| 970 |
+
} else if (!isEditingPlan) {
|
| 971 |
+
// If somehow cancel is clicked but not in edit mode, just reset
|
| 972 |
+
resetCarePlanEditState();
|
| 973 |
}
|
| 974 |
+
// If confirm is false, do nothing (stay in edit mode)
|
| 975 |
+
});
|
| 976 |
+
|
| 977 |
+
$saveBtn.on('click', function() {
|
| 978 |
+
handleSaveCarePlan(); // Trigger the save function
|
| 979 |
});
|
| 980 |
|
| 981 |
|
| 982 |
+
// --- Initial Load and Periodic Checks ---
|
| 983 |
+
|
| 984 |
// Initial patient data load when page is ready
|
| 985 |
loadPatients();
|
| 986 |
|
|
|
|
| 991 |
url: '/get_emergency_notifications',
|
| 992 |
type: 'GET',
|
| 993 |
success: function(response) {
|
| 994 |
+
if (response.success) {
|
| 995 |
+
const emergencyPatients = response.notifications; // Assuming endpoint returns list of emergency patients now
|
| 996 |
+
if (emergencyPatients.length > 0) {
|
| 997 |
+
console.log(`Found ${emergencyPatients.length} emergency notifications.`);
|
| 998 |
+
const alertCount = emergencyPatients.length;
|
| 999 |
+
const newAlertHtml = `
|
| 1000 |
<div class="alert alert-danger mb-3">
|
| 1001 |
<i class="fas fa-exclamation-triangle me-2"></i>
|
| 1002 |
<strong>${alertCount} Emergency patient${alertCount > 1 ? 's' : ''} requiring immediate attention!</strong>
|
| 1003 |
</div>
|
| 1004 |
`;
|
| 1005 |
+
// Only update if the alert content has changed
|
| 1006 |
+
if ($('#emergency-alerts').html().trim() !== newAlertHtml.trim()) {
|
| 1007 |
+
$('#emergency-alerts').html(newAlertHtml);
|
| 1008 |
+
// Reload the patient list to update sorting and potentially highlight new emergencies
|
| 1009 |
+
console.log("Reloading patient list due to new emergency alerts...");
|
| 1010 |
+
loadPatients(); // This will re-render the list and handle selection from URL/previously selected ID
|
| 1011 |
+
}
|
| 1012 |
+
} else {
|
| 1013 |
+
// If no emergencies, clear the alert area
|
| 1014 |
+
console.log("No emergency notifications.");
|
| 1015 |
+
$('#emergency-alerts').empty();
|
| 1016 |
}
|
|
|
|
| 1017 |
} else {
|
| 1018 |
+
console.error("Error checking emergency notifications:", response.error);
|
| 1019 |
+
// Optionally display a small error message in the alert area
|
| 1020 |
+
// $('#emergency-alerts').html('<div class="text-danger small">Error checking alerts.</div>');
|
| 1021 |
}
|
| 1022 |
},
|
| 1023 |
error: function(xhr, status, error) {
|
|
|
|
| 1027 |
}
|
| 1028 |
});
|
| 1029 |
}
|
|
|
|
| 1030 |
// Check for emergency notifications periodically (e.g., every 30 seconds)
|
| 1031 |
setInterval(checkEmergencyNotifications, 30000); // 30 seconds
|
| 1032 |
|
| 1033 |
+
|
| 1034 |
// Handle browser back/forward button for URL patient ID
|
| 1035 |
window.onpopstate = function(event) {
|
| 1036 |
const urlParams = new URLSearchParams(window.location.search);
|
| 1037 |
const patientIdFromUrl = urlParams.get('patient_id');
|
|
|
|
| 1038 |
// Compare with the ID of the patient currently *displayed* in the details pane
|
| 1039 |
// This needs to be tracked separately as loadPatients might be async
|
|
|
|
|
|
|
| 1040 |
|
| 1041 |
+
if (patientIdFromUrl && patientIdFromUrl !== currentlySelectedPatientId) {
|
| 1042 |
console.log(`URL changed to patient ID: ${patientIdFromUrl}. Attempting to load details.`);
|
| 1043 |
+
// Check if currently editing before switching
|
| 1044 |
+
if (isEditingPlan) {
|
| 1045 |
+
if (!confirm("You have unsaved changes. Discard changes and switch patients?")) {
|
| 1046 |
+
history.pushState({ patient_id: currentlySelectedPatientId }, '', `/doctor_dashboard?patient_id=${currentlySelectedPatientId}`); // Put the old URL back
|
| 1047 |
+
return; // Do not switch if user cancels
|
| 1048 |
+
}
|
| 1049 |
+
}
|
| 1050 |
// Check if this ID exists in the currently rendered list before calling API
|
| 1051 |
if ($(`.patient-item[data-id="${patientIdFromUrl}"]`).length > 0) {
|
| 1052 |
loadPatientDetails(patientIdFromUrl);
|
|
|
|
| 1057 |
$('#no-patient-selected').show();
|
| 1058 |
currentlySelectedPatientId = null; // Reset
|
| 1059 |
history.replaceState({}, '', '/doctor_dashboard'); // Clear URL param if not found
|
| 1060 |
+
resetCarePlanEditState(); // Reset edit state
|
| 1061 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 1062 |
}
|
| 1063 |
+
} else if (!patientIdFromUrl && currentlySelectedPatientId) {
|
| 1064 |
// If URL has no ID but a patient is currently displayed, hide details
|
| 1065 |
+
console.log("URL changed, no patient ID. Hiding details.");
|
| 1066 |
+
// Check if currently editing before hiding
|
| 1067 |
+
if (isEditingPlan) {
|
| 1068 |
+
if (!confirm("You have unsaved changes. Discard changes and go back?")) {
|
| 1069 |
+
// Stay on the current page with the patient selected
|
| 1070 |
+
history.pushState({ patient_id: currentlySelectedPatientId }, '', `/doctor_dashboard?patient_id=${currentlySelectedPatientId}`);
|
| 1071 |
+
return; // Do not hide if user cancels
|
| 1072 |
+
}
|
| 1073 |
+
}
|
| 1074 |
$('.patient-item').removeClass('active'); // Remove highlight
|
| 1075 |
$('#patient-details-section').hide();
|
| 1076 |
$('#no-patient-selected').show();
|
| 1077 |
currentlySelectedPatientId = null; // Reset
|
| 1078 |
+
resetCarePlanEditState(); // Reset edit state
|
| 1079 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 1080 |
+
} else if (patientIdFromUrl && patientIdFromUrl === currentlySelectedPatientId) {
|
| 1081 |
// If URL has the same ID as currently displayed, do nothing (user navigated back to the same state)
|
| 1082 |
console.log("URL changed but same patient ID. No action needed.");
|
| 1083 |
} else {
|
|
|
|
| 1087 |
$('#patient-details-section').hide();
|
| 1088 |
$('#no-patient-selected').show();
|
| 1089 |
currentlySelectedPatientId = null; // Reset
|
| 1090 |
+
resetCarePlanEditState(); // Reset edit state
|
| 1091 |
+
$whatsappBtn.hide(); // Hide WhatsApp button
|
| 1092 |
}
|
| 1093 |
};
|
| 1094 |
});
|