/**
* AIMHSA Professional Dashboard JavaScript
* Simplified version without AdminLTE dependencies
*/
(() => {
'use strict';
// API Configuration
let apiRoot;
try {
const loc = window.location;
if (loc.port === '8000') {
apiRoot = `${loc.protocol}//${loc.hostname}:7860`;
} else if (loc.port === '7860' || loc.port === '') {
apiRoot = loc.origin;
} else {
apiRoot = 'https://prodevroger-ishingiro.hf.space';
}
} catch (_) {
apiRoot = 'https://prodevroger-ishingiro.hf.space';
}
const API_ROOT = apiRoot;
// Global variables
let currentSection = 'dashboard';
let charts = {};
let dataTables = {};
let currentUser = null;
// Initialize when DOM is ready
$(document).ready(function() {
console.log('Professional Dashboard Initializing...');
// Initialize components (simplified)
initializeNavigation();
initializeDataTables();
initializeCharts();
initializeEventHandlers();
// Get current user and load data
getCurrentUser();
// Start auto-refresh
startAutoRefresh();
// Force initial data load after a short delay
setTimeout(() => {
console.log('Force loading dashboard data...');
loadDashboardData();
}, 1000);
// Add refresh button functionality
$(document).on('click', '#refreshDashboardBtn', function() {
console.log('Manual dashboard refresh triggered');
loadDashboardData();
});
});
/**
* Initialize basic components (no AdminLTE dependencies)
*/
function initializeBasicComponents() {
// Initialize tooltips if Bootstrap is available
if (typeof $ !== 'undefined' && $.fn.tooltip) {
$('[data-toggle="tooltip"]').tooltip();
}
// Initialize popovers if Bootstrap is available
if (typeof $ !== 'undefined' && $.fn.popover) {
$('[data-toggle="popover"]').popover();
}
}
/**
* Initialize navigation system
*/
function initializeNavigation() {
// Handle sidebar navigation
$('.nav-sidebar .nav-link').on('click', function(e) {
e.preventDefault();
const section = $(this).data('section');
if (section) {
showSection(section);
updateActiveNavItem($(this));
updateBreadcrumb(section);
}
});
// Handle breadcrumb navigation
$('.breadcrumb a').on('click', function(e) {
e.preventDefault();
const section = $(this).attr('href').substring(1);
showSection(section);
});
}
/**
* Show specific section and hide others
*/
function showSection(sectionName) {
// Hide all sections
$('.content-section').hide();
// Show target section
$(`#${sectionName}-section`).show();
// Update current section
currentSection = sectionName;
// Load section-specific data
loadSectionData(sectionName);
}
/**
* Update active navigation item
*/
function updateActiveNavItem(activeItem) {
$('.nav-sidebar .nav-link').removeClass('active');
activeItem.addClass('active');
}
/**
* Update breadcrumb
*/
function updateBreadcrumb(section) {
const sectionNames = {
'dashboard': 'Dashboard',
'sessions': 'My Sessions',
'notifications': 'Notifications',
'reports': 'Reports',
'profile': 'Profile',
'settings': 'Settings'
};
$('#pageTitle').text(sectionNames[section] || 'Dashboard');
$('#breadcrumbActive').text(sectionNames[section] || 'Dashboard');
}
/**
* Initialize DataTables (if available)
*/
function initializeDataTables() {
// Sessions table
if ($('#sessionsTable').length && typeof $ !== 'undefined' && $.fn.DataTable) {
dataTables.sessions = $('#sessionsTable').DataTable({
responsive: true,
processing: true,
serverSide: false,
pageLength: 25,
order: [[0, 'desc']],
columnDefs: [
{ targets: [-1], orderable: false }
],
language: {
search: "Search:",
lengthMenu: "Show _MENU_ entries per page",
info: "Showing _START_ to _END_ of _TOTAL_ entries",
paginate: {
first: "First",
last: "Last",
next: "Next",
previous: "Previous"
}
}
});
}
}
/**
* Initialize charts (if Chart.js is available)
*/
function initializeCharts() {
// Only initialize if Chart.js is available
if (typeof Chart === 'undefined') {
console.log('Chart.js not available, skipping chart initialization');
return;
}
// Session trend chart
if ($('#sessionTrendChart').length) {
const ctx = document.getElementById('sessionTrendChart').getContext('2d');
charts.sessionTrend = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [{
label: 'Completed Sessions',
data: [12, 15, 18, 14, 16, 19],
borderColor: '#28a745',
backgroundColor: 'rgba(40, 167, 69, 0.1)',
tension: 0.4
}, {
label: 'Scheduled Sessions',
data: [8, 12, 10, 15, 13, 17],
borderColor: '#007bff',
backgroundColor: 'rgba(0, 123, 255, 0.1)',
tension: 0.4
}, {
label: 'Cancelled Sessions',
data: [2, 3, 1, 4, 2, 3],
borderColor: '#dc3545',
backgroundColor: 'rgba(220, 53, 69, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// Risk distribution chart
if ($('#riskDistributionChart').length) {
const ctx = document.getElementById('riskDistributionChart').getContext('2d');
charts.riskDistribution = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Low Risk', 'Medium Risk', 'High Risk', 'Critical'],
datasets: [{
data: [45, 35, 15, 5],
backgroundColor: ['#28a745', '#17a2b8', '#ffc107', '#dc3545'],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
}
}
/**
* Initialize Select2 (if available)
*/
function initializeSelect2() {
if (typeof $ !== 'undefined' && $.fn.select2) {
$('.select2').select2({
theme: 'bootstrap4',
width: '100%'
});
}
}
/**
* Initialize event handlers
*/
function initializeEventHandlers() {
// Session management
$('#addNewSessionBtn').on('click', function() {
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#sessionNotesModal').modal('show');
} else {
// Fallback for when Bootstrap modal is not available
document.getElementById('sessionNotesModal').style.display = 'block';
}
});
$('#saveNotesBtn').on('click', function() {
saveSessionNotes();
});
// Follow-up checkbox handler
$('#followUpRequired').on('change', function() {
if ($(this).is(':checked')) {
$('#followUpDateGroup').show();
} else {
$('#followUpDateGroup').hide();
}
});
// Session notes form handler
$('#saveNotesBtn').on('click', function() {
const bookingId = $('#sessionId').val();
const notes = $('#sessionNotes').val();
const followUpRequired = $('#followUpRequired').is(':checked');
const followUpDate = $('#followUpDate').val();
if (!notes.trim()) {
if (typeof Swal !== 'undefined') {
Swal.fire('Error', 'Please enter session notes', 'error');
} else {
alert('Please enter session notes');
}
return;
}
// For now, just show success message
if (typeof Swal !== 'undefined') {
Swal.fire('Success', 'Session notes saved successfully', 'success');
$('#sessionNotesModal').modal('hide');
} else {
alert('Session notes saved successfully');
document.getElementById('sessionNotesModal').style.display = 'none';
}
loadSessions(); // Refresh sessions
});
// Refresh buttons
$('[id$="RefreshBtn"], [id$="refreshBtn"]').on('click', function() {
const section = $(this).closest('.content-section').attr('id').replace('-section', '');
loadSectionData(section);
});
// Filter functionality
$('#sessionStatusFilter, #riskLevelFilter').on('change', function() {
applyFilters();
});
// Logout
$('#logoutBtn').on('click', function() {
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Logout?',
text: 'Are you sure you want to logout?',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, logout!'
}).then((result) => {
if (result.isConfirmed) {
// Clear all session data
localStorage.removeItem('aimhsa_professional');
localStorage.removeItem('aimhsa_account');
localStorage.removeItem('aimhsa_admin');
localStorage.removeItem('currentUser');
// Redirect to login page
window.location.href = '/login.html';
}
});
} else {
// Fallback for when SweetAlert is not available
if (confirm('Are you sure you want to logout?')) {
// Clear all session data
localStorage.removeItem('aimhsa_professional');
localStorage.removeItem('aimhsa_account');
localStorage.removeItem('aimhsa_admin');
localStorage.removeItem('currentUser');
// Redirect to login page
window.location.href = '/login.html';
}
}
});
}
/**
* Get current user information
*/
function getCurrentUser() {
console.log('Getting current user...');
// Check for professional login session
const professionalSession = localStorage.getItem('aimhsa_professional');
if (professionalSession) {
try {
currentUser = JSON.parse(professionalSession);
console.log('Professional user authenticated:', currentUser.name);
updateUserInfo();
loadDashboardData();
return;
} catch (error) {
console.warn('Invalid professional session:', error);
}
}
// Check for other user types and redirect if needed
const userSession = localStorage.getItem('aimhsa_account');
const adminSession = localStorage.getItem('aimhsa_admin');
if (userSession) {
console.warn('User is logged in as regular user, redirecting to login');
alert('You are logged in as a regular user. Please logout and login as a professional.');
window.location.href = '/login.html';
return;
}
if (adminSession) {
console.warn('User is logged in as admin, redirecting to login');
alert('You are logged in as an admin. Please logout and login as a professional.');
window.location.href = '/login.html';
return;
}
// No valid session found - create a test professional session for demo purposes
console.log('No professional session found, creating test session for demo');
createTestProfessionalSession();
}
/**
* Create a test professional session for demo purposes
*/
function createTestProfessionalSession() {
// Create a test professional user
currentUser = {
professional_id: 18,
name: 'Dashboard Test Professional',
username: 'dashboard_test_prof',
email: 'dashboard.test@example.com',
fullname: 'Dashboard Test Professional',
specialization: 'Psychologist'
};
// Store in localStorage
localStorage.setItem('aimhsa_professional', JSON.stringify(currentUser));
console.log('Test professional session created:', currentUser);
updateUserInfo();
loadDashboardData();
}
/**
* Update user information display
*/
function updateUserInfo() {
if (currentUser) {
console.log('Updating UI with user info:', currentUser);
// Update user name in sidebar
$('#professionalNameSidebar').text(currentUser.name || currentUser.fullname || 'Professional');
$('#professionalName').text(currentUser.name || currentUser.fullname || 'Professional');
// Update user role/specialization
$('#professionalRole').text(currentUser.specialization || 'Mental Health Professional');
// Update user email if available
if (currentUser.email) {
$('.user-panel .info span').text(currentUser.email);
}
// Update user profile image with initials
updateUserProfileImage(currentUser.name || currentUser.fullname || 'Professional');
console.log('User info updated:', currentUser.name);
}
}
/**
* Update user profile image with initials
*/
function updateUserProfileImage(fullName) {
if (!fullName) return;
// Extract initials from full name
const initials = fullName.split(' ')
.map(name => name.charAt(0).toUpperCase())
.join('')
.substring(0, 2);
// Create SVG with initials
const svgData = `data:image/svg+xml;base64,${btoa(`
${initials}
`)}`;
// Update the profile image
$('#userProfileImage').attr('src', svgData);
$('#profileUserImage').attr('src', svgData);
}
/**
* Load dashboard data from database
*/
function loadDashboardData() {
console.log('🔄 Loading professional dashboard data...');
if (!currentUser) {
console.log('⚠️ No current user, waiting...');
setTimeout(loadDashboardData, 1000);
return;
}
console.log('✅ Current user found:', currentUser.name);
// Update user info in UI
updateUserInfo();
// Load dashboard statistics from API
loadDashboardStats();
// Load today's schedule
loadTodaySchedule();
// Load recent notifications
loadRecentNotifications();
// Load dashboard charts
loadDashboardCharts();
console.log('✅ Dashboard data loading completed');
}
/**
* Update user information in the UI
*/
function updateUserInfo() {
if (currentUser) {
console.log(' Updating UI with user info:', currentUser);
$('#professionalName').text(currentUser.fullname || currentUser.username);
$('#professionalNameSidebar').text(currentUser.fullname || currentUser.username);
$('#professionalRole').text(currentUser.specialization || 'Mental Health Professional');
$('#profileName').text(currentUser.fullname || currentUser.username);
$('#profileRole').text(currentUser.specialization || 'Mental Health Professional');
}
}
/**
* Load dashboard statistics from API
*/
function loadDashboardStats() {
console.log('Loading dashboard statistics...');
if (!currentUser) {
console.log('No current user for stats');
return;
}
console.log('Fetching data from:', `${API_ROOT}/admin/bookings`);
// Show loading state
$('#totalSessions').html(' ');
$('#unreadNotifications').html(' ');
$('#upcomingToday').html(' ');
$('#highRiskSessions').html(' ');
// Get user's booking statistics
fetch(`${API_ROOT}/admin/bookings`)
.then(response => {
console.log('API response status:', response.status);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Dashboard stats received:', data);
// Calculate statistics
const totalSessions = data.total || 0;
const confirmedSessions = data.confirmed || 0;
const pendingSessions = data.pending || 0;
const criticalSessions = data.critical || 0;
// Calculate today's sessions
const today = new Date().toDateString();
const todaySessions = data.bookings ? data.bookings.filter(booking => {
const bookingDate = new Date(booking.scheduled_datetime * 1000).toDateString();
return bookingDate === today;
}).length : 0;
console.log('Updating UI with:', {
totalSessions,
confirmedSessions,
pendingSessions,
criticalSessions,
todaySessions
});
// Update KPI cards with real data
$('#totalSessions').text(totalSessions);
$('#unreadNotifications').text(pendingSessions + criticalSessions); // Show urgent notifications
$('#upcomingToday').text(todaySessions);
$('#highRiskSessions').text(criticalSessions);
// Update notification badge in navbar
$('#notificationBadge').text(pendingSessions + criticalSessions);
$('#notificationCount').text(pendingSessions + criticalSessions);
// Update notification dropdown
updateNotificationDropdown(data.bookings || []);
console.log('Dashboard statistics updated successfully with real data');
})
.catch(error => {
console.error('Error loading dashboard stats:', error);
// Show error state
$('#totalSessions').html(' ');
$('#unreadNotifications').html(' ');
$('#upcomingToday').html(' ');
$('#highRiskSessions').html(' ');
// Show error message
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Data Loading Error',
text: 'Unable to load dashboard data. Please check your connection and try again.',
icon: 'warning',
timer: 5000,
showConfirmButton: false
});
} else {
console.error('Unable to load dashboard data. Please check your connection and try again.');
}
});
}
/**
* Update notification dropdown with real data
*/
function updateNotificationDropdown(bookings) {
const notificationMenu = $('.dropdown-menu.dropdown-menu-lg');
const urgentBookings = bookings.filter(booking =>
booking.risk_level === 'critical' || booking.booking_status === 'pending'
).slice(0, 5); // Show top 5 urgent items
let notificationHtml = ``;
if (urgentBookings.length === 0) {
notificationHtml += `
All caught up!
No urgent items
`;
} else {
urgentBookings.forEach(booking => {
const timeAgo = getTimeAgo(booking.created_ts);
const icon = booking.risk_level === 'critical' ? 'fa-exclamation-triangle' : 'fa-calendar';
const color = booking.risk_level === 'critical' ? 'text-danger' : 'text-warning';
notificationHtml += `
${booking.user_fullname || 'Patient'} - ${booking.risk_level || 'New booking'}
${timeAgo}
`;
});
}
notificationHtml += `
`;
notificationMenu.html(notificationHtml);
}
/**
* Get time ago string from timestamp
*/
function getTimeAgo(timestamp) {
if (!timestamp) return 'Unknown';
const now = Date.now() / 1000;
const diff = now - timestamp;
if (diff < 60) return 'Just now';
if (diff < 3600) return `${Math.floor(diff / 60)} mins ago`;
if (diff < 86400) return `${Math.floor(diff / 3600)} hours ago`;
return `${Math.floor(diff / 86400)} days ago`;
}
/**
* View booking details modal
*/
window.viewBookingDetails = function(bookingId) {
console.log('Viewing booking details for:', bookingId);
// Find the booking in the current data
fetch(`${API_ROOT}/admin/bookings`)
.then(response => response.json())
.then(data => {
const booking = data.bookings.find(b => b.booking_id === bookingId);
if (booking) {
showBookingDetailsModal(booking);
} else {
Swal.fire('Error', 'Booking not found', 'error');
}
})
.catch(error => {
console.error('Error fetching booking details:', error);
Swal.fire('Error', 'Failed to load booking details', 'error');
});
};
/**
* Show booking details modal
*/
function showBookingDetailsModal(booking) {
const scheduledTime = new Date(booking.scheduled_datetime * 1000).toLocaleString();
const riskBadgeClass = getRiskBadgeClass(booking.risk_level);
const statusBadgeClass = getStatusBadgeClass(booking.booking_status);
const modalHtml = `
Patient Information
Name: ${booking.user_fullname || 'Unknown'}
Email: ${booking.user_email || 'N/A'}
Phone: ${booking.user_phone || 'N/A'}
Location: ${booking.user_location || 'N/A'}
Session Details
Scheduled: ${scheduledTime}
Status: ${booking.booking_status}
Risk Level: ${booking.risk_level}
Session Type: ${booking.session_type || 'Routine'}
${booking.detected_indicators && booking.detected_indicators.length > 0 ? `
Detected Indicators
${booking.detected_indicators.map(indicator => `${indicator} `).join('')}
` : ''}
`;
// Remove existing modal if any
$('#bookingDetailsModal').remove();
// Add modal to body
$('body').append(modalHtml);
// Show modal
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#bookingDetailsModal').modal('show');
} else {
// Fallback for when Bootstrap modal is not available
document.getElementById('bookingDetailsModal').style.display = 'block';
}
};
/**
* Get risk badge class
*/
function getRiskBadgeClass(riskLevel) {
switch (riskLevel) {
case 'critical': return 'danger';
case 'high': return 'warning';
case 'medium': return 'info';
case 'low': return 'success';
default: return 'secondary';
}
}
/**
* Get status badge class
*/
function getStatusBadgeClass(status) {
switch (status) {
case 'confirmed': return 'success';
case 'pending': return 'warning';
case 'completed': return 'info';
case 'cancelled': return 'danger';
default: return 'secondary';
}
}
/**
* Start session function
*/
window.startSession = function(bookingId) {
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Start Session',
text: 'Are you ready to start this session?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, start session',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
// Here you would implement the actual session start logic
Swal.fire('Session Started', 'The session has been started successfully!', 'success');
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#bookingDetailsModal').modal('hide');
} else {
document.getElementById('bookingDetailsModal').style.display = 'none';
}
// Refresh the dashboard data
loadDashboardData();
}
});
} else {
// Fallback for when SweetAlert is not available
if (confirm('Are you ready to start this session?')) {
alert('Session Started! The session has been started successfully!');
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#bookingDetailsModal').modal('hide');
} else {
document.getElementById('bookingDetailsModal').style.display = 'none';
}
// Refresh the dashboard data
loadDashboardData();
}
}
};
/**
* View session function
*/
window.viewSession = function(bookingId) {
console.log('Viewing session:', bookingId);
viewBookingDetails(bookingId);
};
/**
* Add session notes function
*/
window.addSessionNotes = function(bookingId) {
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Add Session Notes',
input: 'textarea',
inputLabel: 'Session Notes',
inputPlaceholder: 'Enter your session notes here...',
inputAttributes: {
'aria-label': 'Type your session notes here'
},
showCancelButton: true,
confirmButtonText: 'Save Notes',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
// Here you would save the notes to the database
Swal.fire('Notes Saved', 'Session notes have been saved successfully!', 'success');
console.log('Session notes for', bookingId, ':', result.value);
}
});
} else {
// Fallback for when SweetAlert is not available
const notes = prompt('Enter your session notes here:');
if (notes !== null && notes.trim() !== '') {
alert('Notes Saved! Session notes have been saved successfully!');
console.log('Session notes for', bookingId, ':', notes);
}
}
};
/**
* Complete session function
*/
window.completeSession = function(bookingId) {
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Complete Session',
text: 'Mark this session as completed?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, complete',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
// Here you would update the session status in the database
Swal.fire('Session Completed', 'The session has been marked as completed!', 'success');
console.log('Session completed:', bookingId);
// Refresh the dashboard data
loadDashboardData();
}
});
} else {
// Fallback for when SweetAlert is not available
if (confirm('Mark this session as completed?')) {
alert('Session Completed! The session has been marked as completed!');
console.log('Session completed:', bookingId);
// Refresh the dashboard data
loadDashboardData();
}
}
};
/**
* Load section-specific data
*/
function loadSectionData(section) {
switch (section) {
case 'sessions':
loadSessions();
break;
case 'notifications':
loadNotifications();
break;
case 'reports':
loadReports();
break;
case 'profile':
loadProfile();
break;
case 'settings':
loadSettings();
break;
case 'dashboard':
loadDashboardCharts();
break;
}
}
/**
* Load dashboard charts
*/
function loadDashboardCharts() {
console.log('Loading dashboard charts...');
// Load session trends chart
loadSessionTrendsChart();
// Load risk distribution chart
loadRiskDistributionChart();
}
/**
* Load session trends chart
*/
function loadSessionTrendsChart() {
// Only proceed if Chart.js is available
if (typeof Chart === 'undefined') {
console.log('Chart.js not available, skipping session trends chart');
return;
}
fetch(`${API_ROOT}/admin/bookings`)
.then(response => response.json())
.then(data => {
const bookings = data.bookings || [];
// Group bookings by date for the last 7 days
const last7Days = [];
for (let i = 6; i >= 0; i--) {
const date = new Date();
date.setDate(date.getDate() - i);
last7Days.push(date.toISOString().split('T')[0]);
}
const sessionData = last7Days.map(date => {
return bookings.filter(booking => {
const bookingDate = new Date(booking.scheduled_datetime * 1000).toISOString().split('T')[0];
return bookingDate === date;
}).length;
});
// Create or update chart
const ctx = document.getElementById('sessionTrendsChart');
if (ctx) {
if (charts.sessionTrends) {
charts.sessionTrends.destroy();
}
charts.sessionTrends = new Chart(ctx, {
type: 'line',
data: {
labels: last7Days.map(date => new Date(date).toLocaleDateString('en-US', { weekday: 'short' })),
datasets: [{
label: 'Sessions',
data: sessionData,
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
stepSize: 1
}
}
}
}
});
}
})
.catch(error => {
console.error('Error loading session trends chart:', error);
});
}
/**
* Load risk distribution chart
*/
function loadRiskDistributionChart() {
// Only proceed if Chart.js is available
if (typeof Chart === 'undefined') {
console.log('Chart.js not available, skipping risk distribution chart');
return;
}
fetch(`${API_ROOT}/admin/bookings`)
.then(response => response.json())
.then(data => {
const bookings = data.bookings || [];
// Count bookings by risk level
const riskCounts = {
low: 0,
medium: 0,
high: 0,
critical: 0
};
bookings.forEach(booking => {
const riskLevel = booking.risk_level || 'low';
if (riskCounts.hasOwnProperty(riskLevel)) {
riskCounts[riskLevel]++;
}
});
// Create or update chart
const ctx = document.getElementById('riskDistributionChart');
if (ctx) {
if (charts.riskDistribution) {
charts.riskDistribution.destroy();
}
charts.riskDistribution = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Low Risk', 'Medium Risk', 'High Risk', 'Critical'],
datasets: [{
data: [riskCounts.low, riskCounts.medium, riskCounts.high, riskCounts.critical],
backgroundColor: [
'rgba(40, 167, 69, 0.8)',
'rgba(23, 162, 184, 0.8)',
'rgba(255, 193, 7, 0.8)',
'rgba(220, 53, 69, 0.8)'
],
borderColor: [
'rgba(40, 167, 69, 1)',
'rgba(23, 162, 184, 1)',
'rgba(255, 193, 7, 1)',
'rgba(220, 53, 69, 1)'
],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
}
})
.catch(error => {
console.error('Error loading risk distribution chart:', error);
});
}
/**
* Load KPI data
*/
function loadKPIData() {
// Simulate API call
setTimeout(() => {
$('#totalSessions').text('15');
$('#unreadNotifications').text('8');
$('#upcomingToday').text('3');
$('#highRiskSessions').text('2');
}, 500);
}
/**
* Load today's schedule
*/
function loadTodaySchedule() {
console.log('Loading today\'s schedule...');
// Load real data from bookings API
fetch(`${API_ROOT}/admin/bookings`)
.then(response => response.json())
.then(data => {
console.log('Schedule data received:', data);
const tbody = $('#todayScheduleTable');
tbody.empty();
if (data.bookings && data.bookings.length > 0) {
// Show first 3 bookings as today's schedule
data.bookings.slice(0, 3).forEach(booking => {
const time = new Date(booking.scheduled_datetime * 1000).toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit'
});
const patientName = booking.user_fullname || booking.user_account || 'Unknown Patient';
const sessionType = booking.session_type || 'Routine';
const status = booking.booking_status;
const row = `
${time}
${patientName}
${sessionType}
${status}
`;
tbody.append(row);
});
} else {
tbody.html('No sessions scheduled for today ');
}
console.log('Today\'s schedule loaded');
})
.catch(error => {
console.error('Error loading schedule:', error);
const tbody = $('#todayScheduleTable');
tbody.html('Error loading schedule ');
});
}
/**
* Load recent notifications
*/
function loadRecentNotifications() {
console.log('Loading recent notifications...');
// For now, show sample notifications
const notifications = [
{
id: 1,
title: 'New Session Booking',
message: 'A new session has been booked for tomorrow at 10:00 AM',
time: new Date().toLocaleString(),
type: 'info',
read: false
},
{
id: 2,
title: 'High Risk Alert',
message: 'A patient has been flagged as high risk and needs immediate attention',
time: new Date(Date.now() - 3600000).toLocaleString(),
type: 'warning',
read: false
},
{
id: 3,
title: 'System Update',
message: 'The system has been updated with new features',
time: new Date(Date.now() - 7200000).toLocaleString(),
type: 'success',
read: true
}
];
console.log('Recent notifications loaded');
}
/**
* Load sessions data
*/
function loadSessions() {
console.log('Loading sessions...');
const tbody = $('#sessionsTableBody');
tbody.html(' Loading sessions... ');
console.log('Fetching from:', `${API_ROOT}/admin/bookings`);
fetch(`${API_ROOT}/admin/bookings`)
.then(response => {
console.log('API response status:', response.status);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Sessions data received:', data);
console.log('Bookings count:', data.bookings ? data.bookings.length : 0);
tbody.empty();
if (data.bookings && data.bookings.length > 0) {
console.log('Processing bookings...');
data.bookings.forEach((booking, index) => {
console.log(`Processing booking ${index + 1}:`, booking.user_fullname || booking.user_account);
const scheduledTime = new Date(booking.scheduled_datetime * 1000).toLocaleString();
const patientName = booking.user_fullname || booking.user_account || 'Unknown Patient';
const row = `
${booking.booking_id.substring(0, 8)}...
${patientName}
${booking.user_email || 'No email'}
${scheduledTime}
${booking.session_type || 'Routine'}
${booking.risk_level}
${booking.booking_status}
`;
tbody.append(row);
});
console.log('All bookings processed successfully');
} else {
console.log('No bookings found in data');
tbody.html(`
No sessions found
`);
}
// Update DataTable if available
if (dataTables.sessions && typeof $ !== 'undefined' && $.fn.DataTable) {
console.log('Updating DataTable...');
dataTables.sessions.clear().rows.add($(tbody).find('tr')).draw();
}
console.log('Sessions loaded successfully');
})
.catch(error => {
console.error('Error loading sessions:', error);
tbody.html(`
Error loading sessions: ${error.message}
`);
});
}
/**
* Load notifications
*/
function loadNotifications() {
console.log('🔔 Loading notifications...');
const container = $('#notificationsList');
container.html(' Loading notifications...
');
// For now, show sample notifications
const notifications = [
{
id: 1,
title: 'New Session Booking',
message: 'A new session has been booked for tomorrow at 10:00 AM',
time: new Date().toLocaleString(),
type: 'info',
read: false
},
{
id: 2,
title: 'High Risk Alert',
message: 'A patient has been flagged as high risk and needs immediate attention',
time: new Date(Date.now() - 3600000).toLocaleString(),
type: 'warning',
read: false
},
{
id: 3,
title: 'System Update',
message: 'The system has been updated with new features',
time: new Date(Date.now() - 7200000).toLocaleString(),
type: 'success',
read: true
}
];
container.empty();
if (notifications.length > 0) {
notifications.forEach(notification => {
const notificationHtml = `
×
${notification.title}
${notification.message}
${notification.time}
${!notification.read ? `
Mark as Read
` : ''}
`;
container.append(notificationHtml);
});
} else {
container.html(`
No notifications found
`);
}
console.log(' Notifications loaded successfully');
}
/**
* Load reports
*/
function loadReports() {
// Reports are already set in HTML
// This function can be used to load dynamic report data
}
/**
* Load profile
*/
function loadProfile() {
// Profile data is already set in HTML
// This function can be used to load dynamic profile data
}
/**
* Load settings
*/
function loadSettings() {
// Settings are already set in HTML
// This function can be used to load dynamic settings
}
/**
* Save session notes
*/
function saveSessionNotes() {
const formData = {
sessionId: $('#sessionId').val(),
patientName: $('#patientName').val(),
sessionNotes: $('#sessionNotes').val(),
followUpRequired: $('#followUpRequired').is(':checked'),
followUpDate: $('#followUpDate').val()
};
// Simulate API call
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Success!',
text: 'Session notes saved successfully.',
icon: 'success',
timer: 2000
}).then(() => {
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#sessionNotesModal').modal('hide');
} else {
document.getElementById('sessionNotesModal').style.display = 'none';
}
loadSessions();
});
} else {
alert('Session notes saved successfully.');
if (typeof $ !== 'undefined' && $.fn.modal) {
$('#sessionNotesModal').modal('hide');
} else {
document.getElementById('sessionNotesModal').style.display = 'none';
}
loadSessions();
}
}
/**
* Apply filters
*/
function applyFilters() {
const status = $('#sessionStatusFilter').val();
const riskLevel = $('#riskLevelFilter').val();
// Apply filters to DataTables if available
if (dataTables.sessions && typeof $ !== 'undefined' && $.fn.DataTable) {
dataTables.sessions.column(5).search(status).draw();
}
}
/**
* Get risk badge class
*/
function getRiskBadgeClass(riskLevel) {
const classes = {
'critical': 'danger',
'high': 'warning',
'medium': 'info',
'low': 'success'
};
return classes[riskLevel.toLowerCase()] || 'secondary';
}
/**
* Get status badge class
*/
function getStatusBadgeClass(status) {
const classes = {
'scheduled': 'info',
'completed': 'success',
'cancelled': 'danger',
'pending': 'warning',
'confirmed': 'success',
'high risk': 'danger'
};
return classes[status.toLowerCase()] || 'secondary';
}
/**
* Get notification icon
*/
function getNotificationIcon(type) {
const icons = {
'info': 'info-circle',
'warning': 'exclamation-triangle',
'success': 'check-circle',
'danger': 'times-circle'
};
return icons[type] || 'info-circle';
}
/**
* Start auto-refresh
*/
function startAutoRefresh() {
setInterval(() => {
if (currentSection === 'dashboard') {
loadDashboardData();
} else {
loadSectionData(currentSection);
}
}, 30000); // Refresh every 30 seconds
}
/**
* Session management functions
*/
window.acceptSession = function(bookingId) {
console.log(' Accepting session:', bookingId);
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Session Accepted!',
text: 'The session has been accepted successfully.',
icon: 'success',
timer: 2000
});
} else {
alert('Session Accepted! The session has been accepted successfully.');
}
loadSessions(); // Refresh sessions
};
window.declineSession = function(bookingId) {
console.log(' Declining session:', bookingId);
if (typeof Swal !== 'undefined') {
Swal.fire({
title: 'Decline Session?',
text: 'Are you sure you want to decline this session?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, decline',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
Swal.fire('Session Declined', 'The session has been declined.', 'success');
loadSessions(); // Refresh sessions
}
});
} else {
if (confirm('Are you sure you want to decline this session?')) {
alert('Session Declined! The session has been declined.');
loadSessions(); // Refresh sessions
}
}
};
window.addSessionNotes = function(bookingId) {
console.log('📝 Adding notes for session:', bookingId);
// Populate modal with session details
$('#sessionId').val(bookingId);
$('#patientName').val('Patient Name');
$('#sessionNotes').val('');
$('#followUpRequired').prop('checked', false);
$('#followUpDateGroup').hide();
// Show modal
$('#sessionNotesModal').modal('show');
};
window.markNotificationRead = function(notificationId) {
console.log('📖 Marking notification as read:', notificationId);
// Remove the notification from the UI
$(`[data-notification-id="${notificationId}"]`).fadeOut();
loadDashboardStats(); // Refresh dashboard stats
};
/**
* Global functions for onclick handlers
*/
window.addNewSession = function() {
$('#sessionNotesModal').modal('show');
};
window.refreshSessions = function() {
loadSessions();
Swal.fire('Refreshed!', 'Sessions data has been refreshed.', 'success');
};
window.markAllAsRead = function() {
Swal.fire('Success!', 'All notifications marked as read.', 'success');
$('#notificationBadge').text('0');
$('#notificationCount').text('0');
};
window.viewSession = function(id) {
Swal.fire('View Session', `View session with ID: ${id}`, 'info');
};
window.editSession = function(id) {
Swal.fire('Edit Session', `Edit session with ID: ${id}`, 'info');
};
// Show dashboard by default
showSection('dashboard');
})();