From d2d34572f658ca42d721724d9d83b9103e343583 Mon Sep 17 00:00:00 2001 From: DevSoftTech Server Date: Thu, 9 Apr 2026 05:49:48 +0530 Subject: [PATCH] Add doctor-customizable foldable consult sections for key OPD fields --- app/Views/billing/opd_prescription_basic.php | 241 ++++++++++++++++++- 1 file changed, 232 insertions(+), 9 deletions(-) diff --git a/app/Views/billing/opd_prescription_basic.php b/app/Views/billing/opd_prescription_basic.php index e1e3e5f..61babee 100644 --- a/app/Views/billing/opd_prescription_basic.php +++ b/app/Views/billing/opd_prescription_basic.php @@ -84,6 +84,42 @@ margin-top: 1rem; padding-top: 1rem; } + .rx-consult-visibility-panel { + display: none; + border: 1px solid #dbe3f8; + background: #f7faff; + border-radius: .5rem; + padding: .65rem; + margin-bottom: .75rem; + } + .rx-consult-visibility-panel .form-check { + min-width: 240px; + margin-right: .75rem; + margin-bottom: .35rem; + } + .rx-foldable { + border: 1px solid #dbe3f8; + border-radius: .5rem; + background: #fff; + padding: .6rem .7rem; + margin-bottom: .65rem; + } + .rx-foldable .rx-fold-heading { + display: flex; + justify-content: space-between; + align-items: center; + gap: .5rem; + margin-bottom: .5rem; + } + .rx-foldable .rx-fold-title { + font-weight: 600; + color: #334155; + margin: 0; + font-size: .92rem; + } + .rx-foldable.is-collapsed .rx-fold-body { + display: none; + } .rx-list-table td, .rx-list-table th { vertical-align: middle; @@ -423,12 +459,51 @@
-
- Single Screen Consult - (Old familiar fields + AI assist) +
+
+ Single Screen Consult + (Old familiar fields + AI assist) +
+
+ Doctor View + +
+
+
+ Doctor Section Visibility + +
+
+ + + + + + +
+
Tip: Click section collapse button to fold/unfold. Settings are saved per doctor.
+
General Examination
@@ -449,7 +524,7 @@
-
+
Pain Measurement Scale
pain_value ?? ''); ?> @@ -470,7 +545,7 @@
-
+
Complication
@@ -484,7 +559,7 @@
-
+
Addiction(if any)
@@ -494,7 +569,7 @@
-
+
Drug Allergy / ADR (NABH)
@@ -615,7 +690,7 @@
0/4000
-
+
@@ -629,7 +704,7 @@
0/4000
-
+
@@ -1125,6 +1200,152 @@ viral_infection: ['CBC', 'LFT', 'KFT'] }; var patientId = id ?? 0) ?>; + var doctorViewId = ; + var consultSectionPreferenceKey = 'opd_consult_section_pref_' + doctorViewId; + var consultSectionMeta = [ + { key: 'pain_scale', selector: '#rx_sec_pain_scale', title: 'Pain Measurement Scale' }, + { key: 'complication', selector: '#rx_sec_complication', title: 'Complication' }, + { key: 'addiction', selector: '#rx_sec_addiction', title: 'Addiction (if any)' }, + { key: 'drug_allergy', selector: '#rx_sec_drug_allergy', title: 'Drug Allergy / ADR (NABH)' }, + { key: 'provisional_diagnosis', selector: '#rx_sec_provisional_diagnosis', title: 'Provisional Diagnosis' }, + { key: 'prescription', selector: '#rx_sec_prescription', title: 'Prescription' } + ]; + + function getConsultSectionDefaultPrefs() { + var out = {}; + consultSectionMeta.forEach(function(meta) { + out[meta.key] = { visible: true, collapsed: false }; + }); + return out; + } + + function loadConsultSectionPrefs() { + var defaults = getConsultSectionDefaultPrefs(); + try { + var raw = localStorage.getItem(consultSectionPreferenceKey); + if (!raw) { + return defaults; + } + var parsed = JSON.parse(raw); + if (!parsed || typeof parsed !== 'object') { + return defaults; + } + consultSectionMeta.forEach(function(meta) { + if (!parsed[meta.key] || typeof parsed[meta.key] !== 'object') { + return; + } + defaults[meta.key].visible = parsed[meta.key].visible !== false; + defaults[meta.key].collapsed = parsed[meta.key].collapsed === true; + }); + return defaults; + } catch (e) { + return defaults; + } + } + + function saveConsultSectionPrefs(prefs) { + try { + localStorage.setItem(consultSectionPreferenceKey, JSON.stringify(prefs || {})); + } catch (e) { + // Ignore private mode/quota errors. + } + } + + function ensureFoldableSectionShell(meta) { + var $sec = $(meta.selector); + if (!$sec.length) { + return; + } + if ($sec.data('foldableReady') === true) { + return; + } + + $sec.addClass('rx-foldable').attr('data-rx-key', meta.key); + + var titleText = meta.title; + var $titleCandidate = $sec.find('h6:first, label.form-label:first'); + if ($titleCandidate.length) { + titleText = ($titleCandidate.first().text() || meta.title).toString().trim(); + $titleCandidate.first().remove(); + } + + var $body = $('
'); + $body.append($sec.contents()); + + var $heading = $('
'); + $heading.append('

'); + $heading.find('.rx-fold-title').text(titleText || meta.title); + $heading.append(''); + + $sec.empty().append($heading).append($body); + $sec.data('foldableReady', true); + } + + function applyConsultSectionPrefs(prefs) { + consultSectionMeta.forEach(function(meta) { + ensureFoldableSectionShell(meta); + var $sec = $(meta.selector); + if (!$sec.length) { + return; + } + + var cfg = (prefs && prefs[meta.key]) ? prefs[meta.key] : { visible: true, collapsed: false }; + var visible = cfg.visible !== false; + var collapsed = cfg.collapsed === true; + + $sec.toggle(visible); + if (!visible) { + return; + } + + $sec.toggleClass('is-collapsed', collapsed); + $sec.find('.rx-fold-toggle').first().text(collapsed ? 'Expand' : 'Fold'); + }); + + $('.rx-consult-visibility-item').each(function() { + var key = ($(this).data('rx-key') || '').toString(); + if (!key || !prefs[key]) { + return; + } + $(this).prop('checked', prefs[key].visible !== false); + }); + } + + function initConsultSectionDesigner() { + var prefs = loadConsultSectionPrefs(); + applyConsultSectionPrefs(prefs); + + $('#btn_toggle_consult_view_settings').off('click').on('click', function() { + $('#rx_consult_visibility_panel').stop(true, true).slideToggle(120); + }); + + $('.rx-consult-visibility-item').off('change').on('change', function() { + var key = ($(this).data('rx-key') || '').toString(); + if (!key || !prefs[key]) { + return; + } + prefs[key].visible = $(this).is(':checked'); + saveConsultSectionPrefs(prefs); + applyConsultSectionPrefs(prefs); + }); + + $(document).off('click.rxFoldToggle').on('click.rxFoldToggle', '.rx-fold-toggle', function() { + var $sec = $(this).closest('.rx-foldable'); + var key = ($sec.data('rx-key') || '').toString(); + if (!key || !prefs[key]) { + return; + } + prefs[key].collapsed = !prefs[key].collapsed; + saveConsultSectionPrefs(prefs); + applyConsultSectionPrefs(prefs); + }); + + $('#btn_reset_consult_view_settings').off('click').on('click', function() { + prefs = getConsultSectionDefaultPrefs(); + saveConsultSectionPrefs(prefs); + applyConsultSectionPrefs(prefs); + }); + } function setAbdmStatus(msg, level) { var $box = $('#abdm_action_status'); @@ -5541,6 +5762,8 @@ loadOldPrescribedPanel(); }); + initConsultSectionDesigner(); + if (localStorage.getItem(draftKey)) { setStatus('dirty', 'Draft available'); }