diff --git a/api/queue.php b/api/queue.php index cf1358d..9b350a0 100644 --- a/api/queue.php +++ b/api/queue.php @@ -79,6 +79,7 @@ try { d.name_$lang as doctor_name, d.name_en as doctor_name_en, d.name_ar as doctor_name_ar, + d.room_number, dept.name_$lang as department_name, dept.name_en as department_name_en, dept.name_ar as department_name_ar diff --git a/check_employees_schema.php b/check_employees_schema.php new file mode 100644 index 0000000..6a85ddc --- /dev/null +++ b/check_employees_schema.php @@ -0,0 +1,8 @@ +query("DESCRIBE employees"); +$columns = $stmt->fetchAll(PDO::FETCH_COLUMN); +echo "Columns in employees table:\n"; +print_r($columns); +?> \ No newline at end of file diff --git a/db/migrations/20260323_add_active_to_departments.sql b/db/migrations/20260323_add_active_to_departments.sql new file mode 100644 index 0000000..a3ab4b3 --- /dev/null +++ b/db/migrations/20260323_add_active_to_departments.sql @@ -0,0 +1 @@ +ALTER TABLE departments ADD COLUMN active BOOLEAN DEFAULT 1; diff --git a/db/migrations/20260323_add_room_number_to_employees.sql b/db/migrations/20260323_add_room_number_to_employees.sql new file mode 100644 index 0000000..329274e --- /dev/null +++ b/db/migrations/20260323_add_room_number_to_employees.sql @@ -0,0 +1 @@ +ALTER TABLE employees ADD COLUMN room_number VARCHAR(50) NULL AFTER email; diff --git a/includes/actions.php b/includes/actions.php index f7f0679..2c6900b 100644 --- a/includes/actions.php +++ b/includes/actions.php @@ -151,9 +151,10 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') $name_en = $_POST['name_en'] ?? ''; $name_ar = $_POST['name_ar'] ?? ''; $show_in_queue = isset($_POST['show_in_queue']) ? 1 : 0; + $active = isset($_POST['active']) ? 1 : 0; if ($name_en && $name_ar) { - $stmt = $db->prepare("INSERT INTO departments (name_en, name_ar, show_in_queue) VALUES (?, ?, ?)"); - $stmt->execute([$name_en, $name_ar, $show_in_queue]); + $stmt = $db->prepare("INSERT INTO departments (name_en, name_ar, show_in_queue, active) VALUES (?, ?, ?, ?)"); + $stmt->execute([$name_en, $name_ar, $show_in_queue, $active]); $_SESSION['flash_message'] = __('add_department') . ' ' . __('successfully'); $redirect = true; } @@ -162,9 +163,10 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') $name_en = $_POST['name_en'] ?? ''; $name_ar = $_POST['name_ar'] ?? ''; $show_in_queue = isset($_POST['show_in_queue']) ? 1 : 0; + $active = isset($_POST['active']) ? 1 : 0; if ($id && $name_en && $name_ar) { - $stmt = $db->prepare("UPDATE departments SET name_en = ?, name_ar = ?, show_in_queue = ? WHERE id = ?"); - $stmt->execute([$name_en, $name_ar, $show_in_queue, $id]); + $stmt = $db->prepare("UPDATE departments SET name_en = ?, name_ar = ?, show_in_queue = ?, active = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $show_in_queue, $active, $id]); $_SESSION['flash_message'] = __('edit_department') . ' ' . __('successfully'); $redirect = true; } @@ -427,12 +429,13 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') $dob = $_POST['dob'] ?: null; $mobile = $_POST['mobile'] ?? ''; $email = $_POST['email'] ?? ''; + $room_number = $_POST['room_number'] ?? ''; $dept_id = $_POST['department_id'] ?: null; $position_id = $_POST['position_id'] ?: null; if ($name_en && $name_ar) { - $stmt = $db->prepare("INSERT INTO employees (name_en, name_ar, dob, mobile, email, department_id, position_id) VALUES (?, ?, ?, ?, ?, ?, ?)"); - $stmt->execute([$name_en, $name_ar, $dob, $mobile, $email, $dept_id, $position_id]); + $stmt = $db->prepare("INSERT INTO employees (name_en, name_ar, dob, mobile, email, room_number, department_id, position_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$name_en, $name_ar, $dob, $mobile, $email, $room_number, $dept_id, $position_id]); $_SESSION['flash_message'] = __('add_employee') . ' ' . __('successfully'); $redirect = true; } @@ -443,12 +446,13 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST') $dob = $_POST['dob'] ?: null; $mobile = $_POST['mobile'] ?? ''; $email = $_POST['email'] ?? ''; + $room_number = $_POST['room_number'] ?? ''; $dept_id = $_POST['department_id'] ?: null; $position_id = $_POST['position_id'] ?: null; if ($id && $name_en && $name_ar) { - $stmt = $db->prepare("UPDATE employees SET name_en = ?, name_ar = ?, dob = ?, mobile = ?, email = ?, department_id = ?, position_id = ? WHERE id = ?"); - $stmt->execute([$name_en, $name_ar, $dob, $mobile, $email, $dept_id, $position_id, $id]); + $stmt = $db->prepare("UPDATE employees SET name_en = ?, name_ar = ?, dob = ?, mobile = ?, email = ?, room_number = ?, department_id = ?, position_id = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $dob, $mobile, $email, $room_number, $dept_id, $position_id, $id]); $_SESSION['flash_message'] = __('edit_employee') . ' ' . __('successfully'); $redirect = true; } diff --git a/includes/pages/departments.php b/includes/pages/departments.php index 3773a63..469ea59 100644 --- a/includes/pages/departments.php +++ b/includes/pages/departments.php @@ -32,7 +32,7 @@ if (isset($_GET['ajax_search'])) { if (empty($departments)): ?> - + @@ -44,12 +44,19 @@ if (isset($_GET['ajax_search'])) { - + + + + + + + +
+
+ + +
@@ -394,6 +413,7 @@ function resetDepartmentModal() { document.getElementById('deptNameEn').value = ''; document.getElementById('deptNameAr').value = ''; + document.getElementById('deptActive').checked = true; document.getElementById('deptShowInQueue').checked = true; } @@ -404,6 +424,7 @@ function showEditDepartmentModal(dept) { document.getElementById('deptNameEn').value = dept.name_en; document.getElementById('deptNameAr').value = dept.name_ar; + document.getElementById('deptActive').checked = (dept.active == 1); document.getElementById('deptShowInQueue').checked = (dept.show_in_queue == 1); var modal = new bootstrap.Modal(document.getElementById('addDepartmentModal')); diff --git a/includes/pages/employees.php b/includes/pages/employees.php index 56d99c4..b2f664f 100644 --- a/includes/pages/employees.php +++ b/includes/pages/employees.php @@ -79,6 +79,7 @@ if (isset($_GET['ajax_search'])) {
+
:
@@ -226,6 +227,7 @@ if (isset($_GET['ajax_search'])) {
+
:
@@ -322,6 +324,12 @@ if (isset($_GET['ajax_search'])) {
+ +
+ + +
+
@@ -330,7 +338,7 @@ if (isset($_GET['ajax_search'])) {
- +
@@ -487,6 +495,7 @@ function resetEmployeeModal() { document.getElementById('empNameAr').value = ''; document.getElementById('empEmail').value = ''; document.getElementById('empMobile').value = ''; + document.getElementById('empRoomNumber').value = ''; document.getElementById('empDob').value = ''; document.getElementById('empDeptId').value = ''; document.getElementById('empPosId').value = ''; @@ -502,6 +511,7 @@ function showEditEmployeeModal(emp) { document.getElementById('empNameAr').value = emp.name_ar; document.getElementById('empEmail').value = emp.email; document.getElementById('empMobile').value = emp.mobile; + document.getElementById('empRoomNumber').value = emp.room_number || ''; document.getElementById('empDob').value = emp.dob; document.getElementById('empDeptId').value = emp.department_id; document.getElementById('empPosId').value = emp.position_id; diff --git a/lang.php b/lang.php index fef2122..b361c5d 100644 --- a/lang.php +++ b/lang.php @@ -439,7 +439,8 @@ $translations = array ( 'smtp_test_failed' => 'SMTP Connection Failed', 'none' => 'None', 'ssl' => 'SSL', - 'tls' => 'TLS' + 'tls' => 'TLS', + 'room_number' => 'Room Number' ), 'ar' => array ( @@ -880,6 +881,7 @@ $translations = array ( 'smtp_test_failed' => 'فشل الاتصال بخادم SMTP', 'none' => 'بدون', 'ssl' => 'SSL', - 'tls' => 'TLS' + 'tls' => 'TLS', + 'room_number' => 'رقم الغرفة' ) -); \ No newline at end of file +); diff --git a/queue_display.php b/queue_display.php index 40f657c..b873733 100644 --- a/queue_display.php +++ b/queue_display.php @@ -34,10 +34,18 @@ try { .header { background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: white; - padding: 20px; - text-align: center; + padding: 15px 20px; + display: flex; + justify-content: space-between; + align-items: center; box-shadow: 0 4px 6px rgba(0,0,0,0.1); - position: relative; + } + .header h1 { + margin: 0; + font-size: 1.8rem; + display: flex; + align-items: center; + gap: 10px; } .dept-card { background: white; @@ -129,10 +137,12 @@ try { 50% { transform: scale(1.05); } 100% { transform: scale(1); } } + .clock-container { + display: flex; + align-items: center; + gap: 15px; + } .clock { - position: absolute; - top: 20px; - right: 20px; font-size: 1.5rem; font-weight: bold; color: white; @@ -164,11 +174,16 @@ try { } - +

Hospital Queue Status / حالة انتظار المستشفى

-
00:00:00
+
+ +
00:00:00
+
@@ -188,6 +203,7 @@ try { let audioEnabled = true; const announcedIds = new Set(); let isFirstRun = true; + let audioContextResumed = false; function updateClock() { const now = new Date(); @@ -196,6 +212,44 @@ try { setInterval(updateClock, 1000); updateClock(); + function enableAudioContext() { + if (!audioContextResumed) { + // Some browsers require a user interaction to allow speech synthesis + if (window.speechSynthesis) { + window.speechSynthesis.resume(); + } + audioContextResumed = true; + } + } + + function toggleSound(e) { + if (e) e.stopPropagation(); // Prevent body onclick + audioEnabled = !audioEnabled; + const icon = document.getElementById('soundIcon'); + const btn = document.getElementById('soundToggle'); + if (audioEnabled) { + icon.className = 'bi bi-volume-up-fill'; + btn.innerHTML = ' Sound: ON'; + btn.classList.remove('btn-outline-danger'); + btn.classList.add('btn-outline-light'); + enableAudioContext(); + + // Test speak + if (window.speechSynthesis) { + const u = new SpeechSynthesisUtterance("Sound enabled"); + window.speechSynthesis.speak(u); + } + } else { + icon.className = 'bi bi-volume-mute-fill'; + btn.innerHTML = ' Sound: OFF'; + btn.classList.remove('btn-outline-light'); + btn.classList.add('btn-outline-danger'); + if (window.speechSynthesis) { + window.speechSynthesis.cancel(); + } + } + } + function fetchQueueStatus() { fetch('api/queue.php?action=list') .then(response => response.json()) @@ -230,17 +284,19 @@ try { } function speakToken(item) { + if (!window.speechSynthesis) return; + // Cancel any pending speech to announce current immediately window.speechSynthesis.cancel(); // English - const textEn = `Token number ${item.token_number}, Department ${item.department_name_en}`; + const textEn = `Token number ${item.token_number}, Room ${item.room_number ? item.room_number : ''}`; const uEn = new SpeechSynthesisUtterance(textEn); uEn.lang = 'en-US'; uEn.rate = 0.9; // Arabic - const textAr = `رقم ${item.token_number}, ${item.department_name_ar}`; + const textAr = `رقم ${item.token_number}, غرفة ${item.room_number ? item.room_number : ''}`; const uAr = new SpeechSynthesisUtterance(textAr); uAr.lang = 'ar-SA'; uAr.rate = 0.8; @@ -294,11 +350,19 @@ try { } else { docName = s.doctor_name || ''; } + + let roomInfo = ''; + if (s.room_number) { + roomInfo = `
Room/غرفة: ${s.room_number}
`; + } return `
${s.token_number}
-
${docName}
+
+ ${docName} + ${roomInfo} +
`; }).join(''); }