adding sound to display
This commit is contained in:
parent
bcd593fb90
commit
04bd70e7d8
@ -4,6 +4,7 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')
|
|||||||
require_once __DIR__ . '/../helpers.php';
|
require_once __DIR__ . '/../helpers.php';
|
||||||
$db = db();
|
$db = db();
|
||||||
|
|
||||||
|
|
||||||
// Check for post_max_size overflow
|
// Check for post_max_size overflow
|
||||||
if (empty($_POST) && empty($_FILES) && isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
|
if (empty($_POST) && empty($_FILES) && isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
|
||||||
$_SESSION['flash_message'] = 'Error: File too large (exceeds post_max_size).';
|
$_SESSION['flash_message'] = 'Error: File too large (exceeds post_max_size).';
|
||||||
@ -310,7 +311,7 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')
|
|||||||
} elseif ($_POST['action'] === 'edit_visit') {
|
} elseif ($_POST['action'] === 'edit_visit') {
|
||||||
$id = $_POST['id'] ?? '';
|
$id = $_POST['id'] ?? '';
|
||||||
// Note: patient_id is not updated as it should be immutable
|
// Note: patient_id is not updated as it should be immutable
|
||||||
$doctor_id = $_POST['doctor_id'] ?? '';
|
$doctor_id = $_POST['doctor_id'] ?: null;
|
||||||
$weight = $_POST['weight'] ?? '';
|
$weight = $_POST['weight'] ?? '';
|
||||||
$bp = $_POST['blood_pressure'] ?? '';
|
$bp = $_POST['blood_pressure'] ?? '';
|
||||||
$hr = $_POST['heart_rate'] ?? '';
|
$hr = $_POST['heart_rate'] ?? '';
|
||||||
@ -343,7 +344,7 @@ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($id && $doctor_id) {
|
if ($id) {
|
||||||
// Removed patient_id from UPDATE
|
// Removed patient_id from UPDATE
|
||||||
$stmt = $db->prepare("UPDATE visits SET doctor_id = ?, weight = ?, blood_pressure = ?, heart_rate = ?, temperature = ?, symptoms = ?, diagnosis = ?, treatment_plan = ?, nursing_notes = ? WHERE id = ?");
|
$stmt = $db->prepare("UPDATE visits SET doctor_id = ?, weight = ?, blood_pressure = ?, heart_rate = ?, temperature = ?, symptoms = ?, diagnosis = ?, treatment_plan = ?, nursing_notes = ? WHERE id = ?");
|
||||||
$stmt->execute([$doctor_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment, $nursing_notes, $id]);
|
$stmt->execute([$doctor_id, $weight, $bp, $hr, $temp, $symptoms, $diagnosis, $treatment, $nursing_notes, $id]);
|
||||||
|
|||||||
@ -1032,7 +1032,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-12 mb-3">
|
<div class="col-md-12 mb-3">
|
||||||
<label class="form-label"><?php echo __("nursing_notes"); ?></label>
|
<label class="form-label"><?php echo __("nursing_notes"); ?></label>
|
||||||
<textarea name="nursing_notes" id="visit_nursing_notes" class="form-control" rows="3"></textarea>
|
<button type="button" class="btn btn-sm btn-outline-info float-end" onclick="generateAISuggestion(this)" data-target="nursing_notes">
|
||||||
|
<i class="bi bi-magic"></i> AI Suggestion
|
||||||
|
</button>
|
||||||
|
<textarea name="nursing_notes" id="visit_nursing_notes" class="form-control summernote" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1387,6 +1390,7 @@ function showRecordVisitModal(patientId = null) {
|
|||||||
$('#visit_symptoms').summernote('code', '');
|
$('#visit_symptoms').summernote('code', '');
|
||||||
$('#visit_diagnosis').summernote('code', '');
|
$('#visit_diagnosis').summernote('code', '');
|
||||||
$('#visit_treatment_plan').summernote('code', '');
|
$('#visit_treatment_plan').summernote('code', '');
|
||||||
|
$('#visit_nursing_notes').summernote('code', '');
|
||||||
|
|
||||||
// Clear dynamic rows
|
// Clear dynamic rows
|
||||||
document.querySelector('#prescriptionTable tbody').innerHTML = '';
|
document.querySelector('#prescriptionTable tbody').innerHTML = '';
|
||||||
@ -1456,7 +1460,6 @@ function showEditVisitModal(data) {
|
|||||||
document.getElementById('visit_blood_pressure').value = data.blood_pressure || '';
|
document.getElementById('visit_blood_pressure').value = data.blood_pressure || '';
|
||||||
document.getElementById('visit_heart_rate').value = data.heart_rate || '';
|
document.getElementById('visit_heart_rate').value = data.heart_rate || '';
|
||||||
document.getElementById('visit_temperature').value = data.temperature || '';
|
document.getElementById('visit_temperature').value = data.temperature || '';
|
||||||
document.getElementById('visit_nursing_notes').value = data.nursing_notes || '';
|
|
||||||
|
|
||||||
// Populate new fields
|
// Populate new fields
|
||||||
$('#visit_patient_gender').val(data.patient_gender || '');
|
$('#visit_patient_gender').val(data.patient_gender || '');
|
||||||
@ -1478,6 +1481,7 @@ function showEditVisitModal(data) {
|
|||||||
$('#visit_symptoms').summernote('code', data.symptoms || '');
|
$('#visit_symptoms').summernote('code', data.symptoms || '');
|
||||||
$('#visit_diagnosis').summernote('code', data.diagnosis || '');
|
$('#visit_diagnosis').summernote('code', data.diagnosis || '');
|
||||||
$('#visit_treatment_plan').summernote('code', data.treatment_plan || '');
|
$('#visit_treatment_plan').summernote('code', data.treatment_plan || '');
|
||||||
|
$('#visit_nursing_notes').summernote('code', data.nursing_notes || '');
|
||||||
|
|
||||||
// Populate prescriptions
|
// Populate prescriptions
|
||||||
const tbody = document.querySelector('#prescriptionTable tbody');
|
const tbody = document.querySelector('#prescriptionTable tbody');
|
||||||
@ -1518,6 +1522,7 @@ function showVisitResultsModal(data) {
|
|||||||
BP: ${data.blood_pressure || '-'},
|
BP: ${data.blood_pressure || '-'},
|
||||||
Weight: ${data.weight || '-'} kg,
|
Weight: ${data.weight || '-'} kg,
|
||||||
Temp: ${data.temperature || '-'}°C
|
Temp: ${data.temperature || '-'}°C
|
||||||
|
, <br>Nursing Notes: ${data.nursing_notes || '-'}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
`;
|
`;
|
||||||
|
|||||||
2
lang.php
2
lang.php
@ -367,6 +367,7 @@ $translations = array (
|
|||||||
'dosage' => 'Dosage',
|
'dosage' => 'Dosage',
|
||||||
'instructions' => 'Instructions',
|
'instructions' => 'Instructions',
|
||||||
'add_drug' => 'Add Drug',
|
'add_drug' => 'Add Drug',
|
||||||
|
'nursing_notes' => 'Nursing Notes',
|
||||||
),
|
),
|
||||||
'ar' =>
|
'ar' =>
|
||||||
array (
|
array (
|
||||||
@ -735,5 +736,6 @@ $translations = array (
|
|||||||
'dosage' => 'الجرعة',
|
'dosage' => 'الجرعة',
|
||||||
'instructions' => 'التعليمات',
|
'instructions' => 'التعليمات',
|
||||||
'add_drug' => 'إضافة دواء',
|
'add_drug' => 'إضافة دواء',
|
||||||
|
'nursing_notes' => 'ملاحظات التمريض',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -37,6 +37,7 @@ try {
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.dept-card {
|
.dept-card {
|
||||||
background: white;
|
background: white;
|
||||||
@ -168,6 +169,9 @@ try {
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<h1 class="m-0"><i class="bi bi-hospital"></i> Hospital Queue Status / حالة انتظار المستشفى</h1>
|
<h1 class="m-0"><i class="bi bi-hospital"></i> Hospital Queue Status / حالة انتظار المستشفى</h1>
|
||||||
<div class="clock" id="clock">00:00:00</div>
|
<div class="clock" id="clock">00:00:00</div>
|
||||||
|
<button id="audioBtn" class="btn btn-warning position-absolute top-0 start-0 m-3" style="z-index: 1001;" onclick="enableAudio()">
|
||||||
|
<i class="bi bi-volume-mute-fill"></i> Enable Sound
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-fluid p-4">
|
<div class="container-fluid p-4">
|
||||||
@ -184,6 +188,17 @@ try {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
let audioEnabled = false;
|
||||||
|
const announcedIds = new Set();
|
||||||
|
let isFirstRun = true;
|
||||||
|
|
||||||
|
function enableAudio() {
|
||||||
|
audioEnabled = true;
|
||||||
|
document.getElementById('audioBtn').style.display = 'none';
|
||||||
|
// Play a silent utterance to unlock audio context on mobile
|
||||||
|
const u = new SpeechSynthesisUtterance('');
|
||||||
|
window.speechSynthesis.speak(u);
|
||||||
|
}
|
||||||
|
|
||||||
function updateClock() {
|
function updateClock() {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@ -197,12 +212,54 @@ try {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
|
checkForNewCalls(data.data);
|
||||||
renderDepartments(data.data);
|
renderDepartments(data.data);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(err => console.error('Fetch error:', err));
|
.catch(err => console.error('Fetch error:', err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkForNewCalls(items) {
|
||||||
|
// Filter for serving items
|
||||||
|
const serving = items.filter(i => i.status === 'serving');
|
||||||
|
|
||||||
|
if (isFirstRun) {
|
||||||
|
// On first load, just mark current serving as announced so we don't spam
|
||||||
|
serving.forEach(i => announcedIds.add(i.id));
|
||||||
|
isFirstRun = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serving.forEach(item => {
|
||||||
|
if (!announcedIds.has(item.id)) {
|
||||||
|
announcedIds.add(item.id);
|
||||||
|
if (audioEnabled) {
|
||||||
|
speakToken(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function speakToken(item) {
|
||||||
|
// 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 uEn = new SpeechSynthesisUtterance(textEn);
|
||||||
|
uEn.lang = 'en-US';
|
||||||
|
uEn.rate = 0.9;
|
||||||
|
|
||||||
|
// Arabic
|
||||||
|
const textAr = `رقم ${item.token_number}, ${item.department_name_ar}`;
|
||||||
|
const uAr = new SpeechSynthesisUtterance(textAr);
|
||||||
|
uAr.lang = 'ar-SA';
|
||||||
|
uAr.rate = 0.8;
|
||||||
|
|
||||||
|
window.speechSynthesis.speak(uEn);
|
||||||
|
window.speechSynthesis.speak(uAr);
|
||||||
|
}
|
||||||
|
|
||||||
function renderDepartments(queueItems) {
|
function renderDepartments(queueItems) {
|
||||||
// Group by department
|
// Group by department
|
||||||
const depts = {};
|
const depts = {};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user