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';
|
||||
$db = db();
|
||||
|
||||
|
||||
// Check for post_max_size overflow
|
||||
if (empty($_POST) && empty($_FILES) && isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
|
||||
$_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') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
// 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'] ?? '';
|
||||
$bp = $_POST['blood_pressure'] ?? '';
|
||||
$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
|
||||
$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]);
|
||||
|
||||
@ -1032,7 +1032,10 @@
|
||||
</div>
|
||||
<div class="col-md-12 mb-3">
|
||||
<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>
|
||||
@ -1387,6 +1390,7 @@ function showRecordVisitModal(patientId = null) {
|
||||
$('#visit_symptoms').summernote('code', '');
|
||||
$('#visit_diagnosis').summernote('code', '');
|
||||
$('#visit_treatment_plan').summernote('code', '');
|
||||
$('#visit_nursing_notes').summernote('code', '');
|
||||
|
||||
// Clear dynamic rows
|
||||
document.querySelector('#prescriptionTable tbody').innerHTML = '';
|
||||
@ -1456,7 +1460,6 @@ function showEditVisitModal(data) {
|
||||
document.getElementById('visit_blood_pressure').value = data.blood_pressure || '';
|
||||
document.getElementById('visit_heart_rate').value = data.heart_rate || '';
|
||||
document.getElementById('visit_temperature').value = data.temperature || '';
|
||||
document.getElementById('visit_nursing_notes').value = data.nursing_notes || '';
|
||||
|
||||
// Populate new fields
|
||||
$('#visit_patient_gender').val(data.patient_gender || '');
|
||||
@ -1478,6 +1481,7 @@ function showEditVisitModal(data) {
|
||||
$('#visit_symptoms').summernote('code', data.symptoms || '');
|
||||
$('#visit_diagnosis').summernote('code', data.diagnosis || '');
|
||||
$('#visit_treatment_plan').summernote('code', data.treatment_plan || '');
|
||||
$('#visit_nursing_notes').summernote('code', data.nursing_notes || '');
|
||||
|
||||
// Populate prescriptions
|
||||
const tbody = document.querySelector('#prescriptionTable tbody');
|
||||
@ -1518,6 +1522,7 @@ function showVisitResultsModal(data) {
|
||||
BP: ${data.blood_pressure || '-'},
|
||||
Weight: ${data.weight || '-'} kg,
|
||||
Temp: ${data.temperature || '-'}°C
|
||||
, <br>Nursing Notes: ${data.nursing_notes || '-'}
|
||||
</dd>
|
||||
</dl>
|
||||
`;
|
||||
|
||||
2
lang.php
2
lang.php
@ -367,6 +367,7 @@ $translations = array (
|
||||
'dosage' => 'Dosage',
|
||||
'instructions' => 'Instructions',
|
||||
'add_drug' => 'Add Drug',
|
||||
'nursing_notes' => 'Nursing Notes',
|
||||
),
|
||||
'ar' =>
|
||||
array (
|
||||
@ -735,5 +736,6 @@ $translations = array (
|
||||
'dosage' => 'الجرعة',
|
||||
'instructions' => 'التعليمات',
|
||||
'add_drug' => 'إضافة دواء',
|
||||
'nursing_notes' => 'ملاحظات التمريض',
|
||||
),
|
||||
);
|
||||
@ -37,6 +37,7 @@ try {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
}
|
||||
.dept-card {
|
||||
background: white;
|
||||
@ -168,6 +169,9 @@ try {
|
||||
<div class="header">
|
||||
<h1 class="m-0"><i class="bi bi-hospital"></i> Hospital Queue Status / حالة انتظار المستشفى</h1>
|
||||
<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 class="container-fluid p-4">
|
||||
@ -184,6 +188,17 @@ try {
|
||||
</div>
|
||||
|
||||
<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() {
|
||||
const now = new Date();
|
||||
@ -197,12 +212,54 @@ try {
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
checkForNewCalls(data.data);
|
||||
renderDepartments(data.data);
|
||||
}
|
||||
})
|
||||
.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) {
|
||||
// Group by department
|
||||
const depts = {};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user