From d2da4004c3993ace5a907597bad57b0c2551f82b Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 2 Apr 2026 15:30:48 +0000 Subject: [PATCH] update css for display --- assets/css/custom.css | 5 +- display.php | 12 ++--- patch.php | 117 ----------------------------------------- patch_audio.js | 87 ------------------------------ patch_css.php | 38 +++++++++++++ patch_css_media.php | 18 +++++++ patch_display.php | 36 +++++++++++++ patch_display_w100.php | 12 +++++ queue_bootstrap.php | 22 +++++--- 9 files changed, 128 insertions(+), 219 deletions(-) delete mode 100644 patch.php delete mode 100644 patch_audio.js create mode 100644 patch_css.php create mode 100644 patch_css_media.php create mode 100644 patch_display.php create mode 100644 patch_display_w100.php diff --git a/assets/css/custom.css b/assets/css/custom.css index d603cd2..8e7233e 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -376,8 +376,9 @@ a:hover { .announcement-card { display: flex; + flex-direction: column; align-items: center; - justify-content: space-between; + justify-content: center; gap: 1rem; padding: 1rem 1.2rem; border: 1px solid var(--border); @@ -538,7 +539,6 @@ html[dir="rtl"] .timeline-list::before { @media (max-width: 767.98px) { .queue-row-head, - .announcement-card, .call-strip, .doctor-spotlight { flex-direction: column; @@ -835,7 +835,6 @@ html[dir="rtl"] .toast-container { html[dir="rtl"] .admin-list-head, html[dir="rtl"] .call-strip, -html[dir="rtl"] .announcement-card, html[dir="rtl"] .admin-sidebar-link { flex-direction: row-reverse; } diff --git a/display.php b/display.php index a705cbf..56d946b 100644 --- a/display.php +++ b/display.php @@ -82,15 +82,15 @@ qh_page_start(
-
+
-
-
+
+
-
-
diff --git a/patch.php b/patch.php deleted file mode 100644 index 3e36e38..0000000 --- a/patch.php +++ /dev/null @@ -1,117 +0,0 @@ - ['class' => 'warning', 'en' => 'Waiting for vitals', 'ar' => 'بانتظار العلامات الحيوية'], -EOD; - -$replace1 = <<<'EOD' -'waiting_vitals' => ['class' => 'warning', 'en' => 'Waiting for vitals', 'ar' => 'بانتظار العلامات الحيوية'], - 'nursing_called' => ['class' => 'primary', 'en' => 'Nursing Call', 'ar' => 'نداء التمريض'], -EOD; -$content = str_replace($search1, $replace1, $content); - -$search2 = <<<'EOD' -SUM(CASE WHEN t.status = 'waiting_vitals' THEN 1 ELSE 0 END) AS vitals_waiting, -EOD; - -$replace2 = <<<'EOD' -SUM(CASE WHEN t.status IN ('waiting_vitals', 'nursing_called') THEN 1 ELSE 0 END) AS vitals_waiting, -EOD; -$content = str_replace($search2, $replace2, $content); - -$search3 = <<<'EOD' -'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status = 'waiting_vitals'")->fetchColumn(), -EOD; - -$replace3 = <<<'EOD' -'waiting_vitals' => (int) $pdo->query("SELECT COUNT(*) FROM hospital_queue_records WHERE item_type = 'ticket' AND DATE(created_at) = CURDATE() AND status IN ('waiting_vitals', 'nursing_called')")->fetchColumn(), -EOD; -$content = str_replace($search3, $replace3, $content); - -$search4 = <<<'EOD' -function qh_call_message(array $ticket): array -{ - $ticketNumber = $ticket['ticket_number'] ?? '---'; - $doctorNameEn = $ticket['doctor_name_en'] ?? 'Doctor'; -EOD; - -$replace4 = <<<'EOD' -function qh_call_message(array $ticket): array -{ - $ticketNumber = $ticket['ticket_number'] ?? '---'; - - if (("ticket['status']" ?? '') === 'nursing_called') { - return [ - 'en' => sprintf('Ticket %s, please proceed to Nursing Station.', $ticketNumber), - 'ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $ticketNumber), - ]; - } - - $doctorNameEn = $ticket['doctor_name_en'] ?? 'Doctor'; -EOD; -$content = str_replace($search4, $replace4, $content); - -$searchHandler = <<<'EOD' - $ticketId = (int) ($_POST['ticket_id'] ?? 0); - $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? '')); - if ($ticketId <= 0 || $vitalsNotes === '') { - throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.')); - } - - $stmt = db()->prepare( - "UPDATE hospital_queue_records - SET vitals_notes = :vitals_notes, - status = 'ready_for_doctor', - display_note = 'Vitals completed. Wait for doctor call.' - WHERE item_type = 'ticket' AND id = :ticket_id AND status = 'waiting_vitals'" - ); - $stmt->execute([ - 'vitals_notes' => $vitalsNotes, - 'ticket_id' => $ticketId, - ]); - qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.')); -EOD; - -$replaceHandler = <<<'EOD' - $ticketId = (int) ($_POST['ticket_id'] ?? 0); - $action = trim((string) ($_POST['action'] ?? 'send')); - - $ticket = qh_fetch_ticket($ticketId); - if (!$ticket) throw new InvalidArgumentException(qh_t('Invalid ticket.', 'تذكرة غير صالحة.')); - - if ($action === 'call_ticket') { - $stmt = db()->prepare( - "UPDATE hospital_queue_records - SET status = 'nursing_called', called_at = NOW(), display_note = :display_note - WHERE item_type = 'ticket' AND id = :ticket_id" - ); - $stmt->execute([ - 'display_note' => sprintf('Ticket %s, proceed to Nursing Station.', $ticket['ticket_number']), - 'ticket_id' => $ticketId - ]); - qh_set_flash('success', qh_t('Patient call was sent to the public display.', 'تم إرسال نداء المريض إلى الشاشة العامة.')); - } else { - $vitalsNotes = trim((string) ($_POST['vitals_notes'] ?? '')); - if ($vitalsNotes === '') throw new InvalidArgumentException(qh_t('Please add a short vitals note before sending the patient forward.', 'يرجى إضافة ملاحظة قصيرة للعلامات الحيوية قبل إرسال المريض.')); - - $stmt = db()->prepare( - "UPDATE hospital_queue_records - SET vitals_notes = :vitals_notes, - status = 'ready_for_doctor', - display_note = 'Vitals completed. Wait for doctor call.' - WHERE item_type = 'ticket' AND id = :ticket_id AND status IN ('waiting_vitals', 'nursing_called')" - ); - $stmt->execute([ - 'vitals_notes' => $vitalsNotes, - 'ticket_id' => $ticketId, - ]); - qh_set_flash('success', qh_t('Vitals captured and patient moved to the doctor queue.', 'تم حفظ العلامات الحيوية ونقل المريض إلى طابور الطبيب.')); - } -EOD; -$content = str_replace($searchHandler, $replaceHandler, $content); - -file_put_contents('queue_bootstrap.php', $content); -echo "SUCCESS!\n"; - -?> \ No newline at end of file diff --git a/patch_audio.js b/patch_audio.js deleted file mode 100644 index ce05434..0000000 --- a/patch_audio.js +++ /dev/null @@ -1,87 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -const jsPath = path.join(__dirname, 'assets/js/main.js'); -let jsCode = fs.readFileSync(jsPath, 'utf8'); - -// Replace the icon logic -jsCode = jsCode.replace( - /audioBtn\.innerHTML = '<\/i>';/g, - `audioBtn.innerHTML = '';` -).replace( - /audioBtn\.innerHTML = '<\/i>';/g, - `audioBtn.innerHTML = '';` -); - -// Add logic to test sound when audio is enabled -const repl1 = `if (nextState) { - initAudio(); - if ('speechSynthesis' in window) { - const primeUtterance = new SpeechSynthesisUtterance(''); - window.speechSynthesis.speak(primeUtterance); - } - }`; -const repl2 = `if (nextState) { - initAudio(); - if ('speechSynthesis' in window) { - const primeUtterance = new SpeechSynthesisUtterance(''); - window.speechSynthesis.speak(primeUtterance); - } - - // Force latest announcement to replay - const cards = Array.from(document.querySelectorAll('.announcement-card')); - const latest = cards[0]; - if (latest) { - const storageKey = -`hospitalQueue:lastAnnouncement:${locale} -`; - window.localStorage.removeItem(storageKey); - setTimeout(checkAnnouncements, 200); - } - }`; -jsCode = jsCode.replace(repl1, repl2); - -// Make sure speech synthesis gets voices early, and handle fallback properly -const oldVoiceLogic = `if (langVoices.length > 0) { - // Try to find a high-quality (Google/Microsoft Natural) voice - const bestVoice = langVoices.find(v => - v.name.includes('Google') || - v.name.includes('Natural') || - v.name.includes('Premium') || - v.name.includes('Online') - ) || langVoices.find(v => v.name.includes('Microsoft')) || langVoices[0]; - - utterance.voice = bestVoice; - }`; - -const newVoiceLogic = `if (langVoices.length > 0) { - // Try to find a high-quality (Google/Microsoft Natural) voice - const bestVoice = langVoices.find(v => - v.name.includes('Google') || - v.name.includes('Natural') || - v.name.includes('Premium') || - v.name.includes('Online') - ) || langVoices.find(v => v.name.includes('Microsoft')) || langVoices[0]; - - utterance.voice = bestVoice; - } else if (voices.length > 0) { - // Fallback to any available voice to ensure sound plays - utterance.voice = voices[0]; - }`; - -jsCode = jsCode.replace(oldVoiceLogic, newVoiceLogic); - -// Call getVoices early -if (!jsCode.includes('window.speechSynthesis.getVoices();')) { - jsCode = jsCode.replace( - `document.addEventListener('DOMContentLoaded', () => {`, - `document.addEventListener('DOMContentLoaded', () => { - if ('speechSynthesis' in window) { - window.speechSynthesis.onvoiceschanged = () => { window.speechSynthesis.getVoices(); }; - window.speechSynthesis.getVoices(); - }` - ); -} - -fs.writeFileSync(jsPath, jsCode); -console.log('patched'); diff --git a/patch_css.php b/patch_css.php new file mode 100644 index 0000000..d99c6d1 --- /dev/null +++ b/patch_css.php @@ -0,0 +1,38 @@ + +
+
+
+ +
+
+ +HTML; + +$replace = <<<'HTML' +
+
+
+
+ +
+
+ +
+
+HTML; + +$newContent = str_replace($search, $replace, $content); +if ($newContent !== $content) { + file_put_contents('display.php', $newContent); + echo "Replaced successfully\n"; +} else { + echo "Pattern not found\n"; +} + diff --git a/patch_display_w100.php b/patch_display_w100.php new file mode 100644 index 0000000..1d38b95 --- /dev/null +++ b/patch_display_w100.php @@ -0,0 +1,12 @@ +'; +$replace = '
'; +$newContent = str_replace($search, $replace, $content); +if ($newContent !== $content) { + file_put_contents('display.php', $newContent); + echo "Added w-100 to card-body\n"; +} else { + echo "w-100 already added or not found\n"; +} + diff --git a/queue_bootstrap.php b/queue_bootstrap.php index 305435c..efc18a4 100644 --- a/queue_bootstrap.php +++ b/queue_bootstrap.php @@ -972,14 +972,24 @@ function qh_status_badge(string $status): string function qh_call_message(array $ticket): array { $ticketNumber = $ticket['ticket_number'] ?? '---'; - $spokenTicket = trim(preg_replace('/([a-zA-Z])/u', '$1, ', str_replace('-', ' ', $ticketNumber))); - + // For English speech, replacing the hyphen with a space helps it say "DRR 001" instead of "DRR minus 001" + $speechEn = strtoupper(str_replace('-', ' ', $ticketNumber)); + + // Map English letters to Arabic phonetics so Arabic TTS pronounces them correctly + $arMap = [ + 'A'=>'إيه ', 'B'=>'بي ', 'C'=>'سي ', 'D'=>'دي ', 'E'=>'إي ', 'F'=>'إف ', 'G'=>'جي ', 'H'=>'إتش ', + 'I'=>'آي ', 'J'=>'جيه ', 'K'=>'كيه ', 'L'=>'إل ', 'M'=>'إم ', 'N'=>'إن ', 'O'=>'أو ', 'P'=>'بي ', + 'Q'=>'كيو ', 'R'=>'آر ', 'S'=>'إس ', 'T'=>'تي ', 'U'=>'يو ', 'V'=>'في ', 'W'=>'دبليو ', 'X'=>'إكس ', + 'Y'=>'واي ', 'Z'=>'زِد ' + ]; + $speechAr = trim(preg_replace('/ +/', ' ', strtr($speechEn, $arMap))); + if (($ticket['status'] ?? '') === 'nursing_called') { return [ 'en' => sprintf('Ticket %s, please proceed to Nursing Station.', $ticketNumber), 'ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $ticketNumber), - 'speech_en' => sprintf('Ticket %s, please proceed to Nursing Station.', $spokenTicket), - 'speech_ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $spokenTicket), + 'speech_en' => sprintf('Ticket %s, please proceed to Nursing Station.', $speechEn), + 'speech_ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى محطة التمريض.', $speechAr), ]; } @@ -990,8 +1000,8 @@ function qh_call_message(array $ticket): array return [ 'en' => sprintf('Ticket %s, please proceed to room %s for %s.', $ticketNumber, $room, $doctorNameEn), 'ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى الغرفة %s إلى %s.', $ticketNumber, $room, $doctorNameAr), - 'speech_en' => sprintf('Ticket %s, please proceed to room %s for %s.', $spokenTicket, $room, $doctorNameEn), - 'speech_ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى الغرفة %s إلى %s.', $spokenTicket, $room, $doctorNameAr), + 'speech_en' => sprintf('Ticket %s, please proceed to room %s for %s.', $speechEn, $room, $doctorNameEn), + 'speech_ar' => sprintf('رقم التذكرة %s، يرجى التوجه إلى الغرفة %s إلى %s.', $speechAr, $room, $doctorNameAr), ]; }