1 {% extends "portal/base.html.twig" %}
6 <link href="../portal/sign/css/signer_modal.css?v={{ assetVersion | attr }}" rel="stylesheet" />
7 <script src="../interface/main/tabs/js/dialog_utils.js?v={{ assetVersion | attr }}"></script>
8 <script src="../portal/sign/assets/signature_pad.umd.js?v={{ assetVersion | attr }}"></script>
9 <script src="../portal/sign/assets/signer_api.js?v={{ assetVersion | attr }}"></script>
11 {% if payment_gateway == 'Stripe' %}
12 <script src="https://js.stripe.com/v3/"></script>
15 {% if payment_gateway == 'AuthorizeNet' %}
16 {% if gateway_mode_production %}
17 <script src="https://js.authorize.net/v1/Accept.js"></script>
19 <script src="https://jstest.authorize.net/v1/Accept.js"></script>
24 var cpid = {{ patientID | js_escape }},
25 cuser = {{ user | js_escape }},
26 webRoot = {{ web_root | js_escape }},
27 ptName = {{ patientName | js_escape }},
28 whereto = {{ whereto | js_escape }},
29 webroot_url = webRoot,
33 function restoreSession() {
37 function persist(where, portalInit = false) {
38 if (where[0] !== '#') {
42 fetch('lib/persist.php', {
45 'Content-Type': 'application/json',
49 'csrf_token_form': {{ csrfUtils | js_escape }},
51 'portal_init': portalInit
58 $('#topNav [data-parent="#cardgroup"]').on('click', (e) => {
59 persist($(e.target).attr('href'), false);
62 if ($('body').css('direction') == "rtl") {
63 $('.float-left').each(function () {
64 $(this).addClass('float-right').removeClass('float-left');
66 $('.dropdown-menu-right').each(function () {
67 $(this).removeClass('dropdown-menu-right');
69 $('.dropdown-menu-md-right').each(function () {
70 $(this).removeClass('dropdown-menu-md-right');
74 $("#profilereport").load("get_profile.php", {}, function () {
75 $("table").addClass("table table-sm");
76 $(".demographics td").removeClass("label");
77 $(".demographics td").addClass("bold");
78 $(".insurance table").addClass("table-sm table-striped");
79 $("#editDems").click(function () {
84 $("#medicationlist").load("./get_medications.php", {}, function () {
87 $("#labresults").load("./get_lab_results.php", {}, function () {
90 $("#amendmentslist").load("./get_amendments.php", {}, function () {
93 $("#problemslist").load("./get_problems.php", {}, function () {
96 $("#allergylist").load("./get_allergies.php", {}, function () {
99 $("#reports").load("./report/portal_patient_report.php?pid=" + {{ patientID | js_url }}, {}, function () {
103 {% if portal_two_payments %}
104 $("#payment").load("./portal_payment.php", {}, function () {
108 $(".generateDoc_download").click(function () {
109 $("#doc_form").submit();
112 function showProfileModal() {
113 var title = {{ 'Profile Edits Red = Charted Values and Blue = Patient Edits' | xlj }};
117 text: {{ 'Help' | xlj }},
123 text: {{ 'Cancel' | xlj }},
128 text: {{ 'Revert Edits' | xlj }},
131 id: 'replaceAllButton'
134 text: {{ 'Submit Changes' | xlj }},
137 id: 'donePatientButton'
142 resolvePromiseOn: 'init',
144 url: webRoot + '/portal/patient/patientdata?pid=' + encodeURIComponent(cpid) + '&user=' + encodeURIComponent(cuser)
147 dlgopen('', '', 'modal-xl', 500, '', title, params).then(function (dialog) {
148 $('div.modal-body', dialog).addClass('overflow-auto');
152 function saveProfile() {
156 var gowhere = {{ whereto | js_escape }};
158 $(gowhere).collapse('show');
160 $('#cardgroup').on('hide.bs.collapse', '.show', function (e) {
161 let target = this.attributes.id.nodeValue;
162 if (whereto.includes(target)) {
168 $('#popwait').addClass('d-none');
170 $('#callccda').click(function () {
171 $('#popwait').removeClass('d-none');
175 function editAppointment(mode, deid) {
179 if (mode === 'add') {
180 title = {{ 'Request New Appointment' | xlj }};
184 } else if (mode === 'recurring') {
185 let msg = {{ 'A Recurring Appointment. Please contact your appointment desk for any changes.' | xlj }};
186 signerAlertMsg(msg, 8000);
189 title = {{ 'Edit Appointment' | xlj }};
197 buttons: [{text: 'Cancel', close: true, style: 'btn-sm btn-secondary'}],
202 url: './add_edit_event_user.php',
206 * A couple notes on dialog.ajax .alert etc.
207 * opener is not required. library will handle for you.
208 * these run in the same scope as calling script.
209 * so same styles, dependencies are in scope.
210 * a promise is returned for doing other neat stuff.
216 function changeCredentials(e) {
217 title = {{ 'Please Enter New Credentials' | xlj }};
218 dlgopen("./account/index_reset.php", '', 575, 600, null, title, {});
223 $("#pro").load("./get_pro.php", {}, function () {
226 function writeResult(score, stdErr, assessmentOID) {
228 url: '../library/ajax/easipro_util.php',
230 'csrf_token_form': {{ csrfUtils | js_escape }},
231 'function': 'record_result',
234 'assessmentOID': assessmentOID
241 function selectResponse(obj, assessmentOID) {
243 url: '../library/ajax/easipro_util.php',
246 'csrf_token_form': {{ csrfUtils | js_escape }},
247 'function': 'select_response',
248 'assessmentOID': assessmentOID,
249 'ItemResponseOID': obj.name,
253 success: function (data) {
254 if (data.DateFinished != '') {
255 document.getElementById("Content").innerHTML = jsText({{ 'You have finished the assessment.' | xlj }}) + "<br /> " + jsText({{ 'Thank you' | xlj }});
256 document.getElementById("asst_" + assessmentOID).innerHTML = "<i class='fa fa-check-circle'></i>";
257 document.getElementById("asst_status_" + assessmentOID).innerHTML = "completed";
259 url: '../library/ajax/easipro_util.php',
262 'csrf_token_form': {{ csrfUtils | js_escape }},
263 'function': 'collect_results',
264 'assessmentOID': assessmentOID
267 success: function (data) {
268 writeResult(data.Items[0].Theta, data.Items[0].StdError, assessmentOID);
275 for (var j = 0; j < data.Items[0].Elements.length; j++) {
276 if (typeof (data.Items[0].Elements[j].Map) == 'undefined') {
277 screen = `<div style="height: 30px>${data.Items[0].Elements[j].Description}</div>`
279 for (var k = 0; k < data.Items[0].Elements[j].Map.length; k++) {
280 screen = `<div style="height: 50px"><input type="button" class="btn-submit" id="${data.Items[0].Elements[j].Map[k].Value}" name="${data.Items[0].Elements[j].Map[k].ItemResponseOID}" value="${data.Items[0].Elements[j].Map[k].Description}" onclick=selectResponse(this,${assessmentOID}) /></div>`;
284 document.getElementById("Content").innerHTML = screen;
286 error: function (jqXHR, textStatus, errorThrown) { // document.write(jqXHR.responseText + ':' + textStatus + ':' + errorThrown);
287 alert("An error occurred");
292 function startAssessment(param, assessmentOID) {
293 param.innerHTML = "<i class='fa fa-circle-notch fa-spin'></i> " + jsText({{ 'Loading' | xlj }});
296 url: '../library/ajax/easipro_util.php',
299 'csrf_token_form': {{ csrfUtils | js_escape }},
300 'function': 'start_assessment',
301 'assessmentOID': assessmentOID
304 success: function (data) {
306 for (var j = 0; j < data.Items[0].Elements.length; j++) {
307 if (typeof (data.Items[0].Elements[j].Map) == 'undefined') {
308 screen = `<div style="height: 30px">${data.Items[0].Elements[j].Description}</div>`;
310 for (var k = 0; k < data.Items[0].Elements[j].Map.length; k++) {
311 screen = `<div style="height: 50px"><input type="button" class='btn-submit' id="${data.Items[0].Elements[j].Map[k].Value}" name="${data.Items[0].Elements[j].Map[k].ItemResponseOID}" value="${data.Items[0].Elements[j].Map[k].Description}" onclick=selectResponse(this, ${assessmentOID})/></div>`;
316 document.getElementById("Content").innerHTML = screen;
318 param.innerHTML = jsText({{ 'Start Assessment' | xlj }});
320 error: function (jqXHR, textStatus, errorThrown) {
321 param.innerHTML = jsText({{ 'Start Assessment' | xlj }});
323 // document.write(jqXHR.responseText);
324 alert("An error occurred");
331 {{ fireEvent(eventNames.scriptsRenderPre) }}
335 {% block pagetitle %}
336 {{ pagetitle | text }}
340 {% include "portal/header.html.twig" %}
345 <section class="flex-column accordion" id="cardgroup">
346 <div id="popwait" class="alert alert-warning d-none">
347 <strong>{{ 'Working!' | xlt }}</strong>
348 {{ 'Please wait...' | xlt }}</div>
350 <div class="collapse overflow-auto" data-parent="#cardgroup" id="lists">
352 <header class="card-header bg-primary text-light">{{ 'Medications' | xlt }}</header>
353 <div id="medicationlist" class="card-body bg-light"></div>
356 <header class="card-header bg-primary text-light">{{ 'Medications Allergy List' | xlt }}</header>
357 <div id="allergylist" class="card-body bg-light"></div>
360 <header class="card-header bg-primary text-light">{{ 'Issues List' | xlt }}</header>
361 <div id="problemslist" class="card-body bg-light"></div>
364 <header class="card-header bg-primary text-light">{{ 'Amendment List' | xlt }}</header>
365 <div id="amendmentslist" class="card-body bg-light"></div>
368 <header class="card-header bg-primary text-light">{{ 'Lab Results' | xlt }}</header>
369 <div id="labresults" class="card-body bg-light"></div>
373 <div class="card collapse overflow-auto" data-parent="#cardgroup" id="reportcard">
374 <header class="card-header bg-primary text-light">{{ 'Reports' | xlt }}</header>
375 <div id="reports" class="card-body"></div>
378 <div class="card collapse" data-parent="#cardgroup" id="profilecard">
379 <div id="profilereport" class="card-body bg-light"></div>
382 <div class="collapse" data-parent="#cardgroup" id="documentscard">
384 <div id="patdocuments" class="card-body">
385 <iframe src="{{ web_root | attr }}/portal/patient/onsitedocuments?pid={{ patientID | attr_url }}" class="w-100 vh-100 border-0"></iframe>
390 <div class="collapse" data-parent="#cardgroup" id="secure-msgs-card">
392 <div id="secure-msgs" class="card-body">
393 <iframe src="{{ web_root | attr }}/portal/messaging/messages.php" class="w-100 vh-100 border-0"></iframe>
398 {% if allow_portal_appointments %}
399 <div class="collapse mt-2 overflow-auto" data-parent="#cardgroup" id="appointmentcard">
400 <div class="container-fluid">
401 <h3 class="text-center">{{ 'Appointments' | xlt }}</h3>
403 {% if appointments|length > 0 %}
404 {% for appt in appointments %}
405 {% include 'portal/appointment-item.html.twig' with {appt: appt} %}
408 {% if appointmentLimit == appointmentCount %}
409 <p>{{ 'Display limit reached' | xlt }}
411 {{ 'More appointments may exist' | xlt }}</p>
414 <h3 class='text-center'>{{ 'No Appointments' | xlt }}</h3>
419 <a class='btn btn-primary btn-block' href='#' onclick="editAppointment('add',{{ patientID | attr_js }})">{{ 'Schedule A New Appointment' | xlt }}</a>
426 {% if portal_two_payments %}
427 <div class="collapse overflow-auto" data-parent="#cardgroup" id="paymentcard">
429 <header class="card-header bg-primary text-light">{{ 'Payments' | xlt }}</header>
430 <div id="payment" class="card-body bg-light"></div>
435 {% if allow_portal_chat %}
436 <div class="collapse overflow-auto" data-parent="#cardgroup" id="messagescard">
437 <div class="card pt-0 pb-0">
438 <header class="card-header bg-primary text-light">{{ 'Secure Chat' | xlt }}</header>
439 <div id="chat" class="card-body p-0 overflow-auto">
440 <iframe src="./messaging/secure_chat.php" class="w-100" style="height: calc(100vh - 120px);"></iframe>
446 {% if portal_onsite_document_download %}
447 <div class="card collapse overflow-auto" data-parent="#cardgroup" id="downloadcard">
448 <header class="card-header bg-primary text-light">{{ 'Download Documents' | xlt }}</header>
449 <div id="docsdownload" class="card-body">
451 <span class="text">{{ 'Download all patient documents' | xlt }}</span>
452 <form name='doc_form' id='doc_form' action='./get_patient_documents.php' method='post'>
453 <input type="button" class="generateDoc_download" value="{{ 'Download' | xla }}" />
461 {% if portal_two_ledger %}
462 <div class="collapse overflow-auto" data-parent="#cardgroup" id="ledgercard">
464 <header class="card-header bg-primary text-light">{{ 'Ledger' | xlt }}</header>
465 <div id="patledger" class="card-body">
466 <iframe src="./report/pat_ledger.php" class="w-100 vh-100 border-0"></iframe>
473 <div class="card collapse overflow-auto" data-parent="#cardgroup" id="procard">
474 <header class="card-header bg-primary text-light">{{ 'Patient Reported Outcomes' | xlt }}</header>
475 <div id="pro" class="card-body bg-light"></div>
479 {{ fireEvent(eventNames.sectionRenderPost) }}