adding ai generation

This commit is contained in:
Flatlogic Bot 2026-03-05 05:14:09 +00:00
parent c6904a9a5e
commit c8679068a9
17 changed files with 217 additions and 101 deletions

View File

@ -5,28 +5,53 @@ require_once __DIR__ . '/../ai/LocalAIApi.php';
// Get JSON input
$input = json_decode(file_get_contents('php://input'), true);
$target = $input['target'] ?? 'treatment_plan'; // symptoms, diagnosis, treatment_plan
$symptoms = $input['symptoms'] ?? '';
$diagnosis = $input['diagnosis'] ?? '';
$currentValue = $input['current_value'] ?? ''; // For expanding symptoms
if (empty($symptoms) && empty($diagnosis)) {
$systemPrompt = 'You are a professional medical assistant.';
$userPrompt = "";
switch ($target) {
case 'symptoms':
if (empty($currentValue)) {
$userPrompt = "Generate a list of common clinical symptoms for a general checkup in a professional medical format (HTML lists).";
} else {
$userPrompt = "Rewrite and expand the following patient symptoms into a professional clinical description using HTML (bullet points or paragraph). Maintain the original meaning but make it clearer and more detailed:\n\n" . strip_tags($currentValue);
}
break;
case 'diagnosis':
if (empty($symptoms)) {
echo json_encode(['success' => false, 'error' => 'Please enter symptoms first to get a diagnosis suggestion.']);
exit;
}
$userPrompt = "Based on the following symptoms, suggest a list of potential differential diagnoses. Provide the response in a clear HTML list format.\n\nSymptoms:\n" . strip_tags($symptoms);
break;
case 'treatment_plan':
default:
if (empty($symptoms) && empty($diagnosis)) {
echo json_encode(['success' => false, 'error' => 'No symptoms or diagnosis provided.']);
exit;
}
$userPrompt = "Based on the following symptoms and diagnosis, please generate a concise treatment plan and medical report for the patient.\n\n";
if (!empty($symptoms)) {
$userPrompt .= "Symptoms:\n" . strip_tags($symptoms) . "\n\n";
}
if (!empty($diagnosis)) {
$userPrompt .= "Diagnosis:\n" . strip_tags($diagnosis) . "\n\n";
}
$userPrompt .= "Please provide the report in a clear, professional format using HTML tags (like <ul>, <li>, <strong>, etc.) for better readability.";
break;
}
$prompt = "You are a professional medical assistant. Based on the following symptoms and diagnosis, please generate a concise treatment plan and medical report for the patient.\n\n";
if (!empty($symptoms)) {
$prompt .= "Symptoms:\n" . strip_tags($symptoms) . "\n\n";
}
if (!empty($diagnosis)) {
$prompt .= "Diagnosis:\n" . strip_tags($diagnosis) . "\n\n";
}
$prompt .= "Please provide the report in a clear, professional format using HTML tags (like <ul>, <li>, <strong>, etc.) for better readability.";
try {
$response = LocalAIApi::createResponse([
'input' => [
['role' => 'system', 'content' => 'You are a helpful medical assistant.'],
['role' => 'user', 'content' => $prompt],
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $userPrompt],
],
]);
@ -39,4 +64,3 @@ try {
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

View File

@ -1,47 +1,83 @@
async function generateAIReport(button) {
async function generateAISuggestion(button) {
const target = button.dataset.target || 'treatment_plan';
const modal = button.closest(".modal");
// Get editor instances or DOM elements
const symptomsEditor = $(modal.querySelector('textarea[name="symptoms"]'));
const diagnosisEditor = $(modal.querySelector('textarea[name="diagnosis"]'));
const treatmentPlanEditor = $(modal.querySelector('textarea[name="treatment_plan"]'));
const symptomsText = symptomsEditor.length && symptomsEditor.summernote ? symptomsEditor.summernote('code') : (modal.querySelector('textarea[name="symptoms"]') ? modal.querySelector('textarea[name="symptoms"]').value : '');
const diagnosisText = diagnosisEditor.length && diagnosisEditor.summernote ? diagnosisEditor.summernote('code') : (modal.querySelector('textarea[name="diagnosis"]') ? modal.querySelector('textarea[name="diagnosis"]').value : '');
// Helper to get value from Summernote or textarea
const getValue = (editor, selector) => {
if (editor.length && editor.summernote) return editor.summernote('code');
const el = modal.querySelector(selector);
return el ? el.value : '';
};
// Check if actually empty beyond HTML tags
const symptomsText = getValue(symptomsEditor, 'textarea[name="symptoms"]');
const diagnosisText = getValue(diagnosisEditor, 'textarea[name="diagnosis"]');
// Helper to set value
const setValue = (editor, selector, val) => {
if (editor.length && editor.summernote) {
editor.summernote('code', val);
} else {
const el = modal.querySelector(selector);
if (el) el.value = val;
}
};
// Validation
const cleanSymptoms = symptomsText.replace(/<[^>]*>/g, "").trim();
const cleanDiagnosis = diagnosisText.replace(/<[^>]*>/g, "").trim();
if (!cleanSymptoms && !cleanDiagnosis) {
if (target === 'diagnosis' && !cleanSymptoms) {
alert("Please enter symptoms first.");
return;
}
if (target === 'treatment_plan' && (!cleanSymptoms && !cleanDiagnosis)) {
alert("Please enter symptoms or diagnosis first.");
return;
}
const originalHTML = button.innerHTML;
button.disabled = true;
button.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> AI generating...';
button.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> AI...';
try {
const payload = {
target: target,
symptoms: symptomsText,
diagnosis: diagnosisText,
current_value: (target === 'symptoms' ? symptomsText : (target === 'diagnosis' ? diagnosisText : ''))
};
const response = await fetch("api/ai_report.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ symptoms: symptomsText, diagnosis: diagnosisText })
body: JSON.stringify(payload)
});
const data = await response.json();
if (data.success) {
if (treatmentPlanEditor.length && treatmentPlanEditor.summernote) {
treatmentPlanEditor.summernote('code', data.report);
if (target === 'symptoms') {
setValue(symptomsEditor, 'textarea[name="symptoms"]', data.report);
} else if (target === 'diagnosis') {
setValue(diagnosisEditor, 'textarea[name="diagnosis"]', data.report);
} else {
modal.querySelector('textarea[name="treatment_plan"]').value = data.report;
setValue(treatmentPlanEditor, 'textarea[name="treatment_plan"]', data.report);
}
} else {
alert("AI Error: " + (data.error || "Unknown error"));
}
} catch (error) {
console.error("AI Report generation failed:", error);
console.error("AI Suggestion failed:", error);
alert("Failed to generate AI suggestion.");
} finally {
button.disabled = false;
button.innerHTML = originalHTML;
}
}
// Alias for backward compatibility
window.generateAIReport = generateAISuggestion;

View File

@ -47,3 +47,25 @@ function calculate_age($dob) {
return '-';
}
}
if (!function_exists('mb_strimwidth')) {
function mb_strimwidth($string, $start, $width, $trimmarker = '...', $encoding = null) {
// Simple polyfill using substr
// 1. Handle start offset
$string = (string)$string;
if ($start > 0) {
$string = substr($string, $start);
}
// 2. Check length
if (strlen($string) <= $width) {
return $string;
}
// 3. Truncate
$targetLen = $width - strlen($trimmarker);
if ($targetLen < 0) $targetLen = 0;
return substr($string, 0, $targetLen) . $trimmarker;
}
}

View File

@ -1269,17 +1269,27 @@
</div>
<hr>
<div class="mb-3">
<label class="form-label"><?php echo __('symptoms'); ?></label>
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __('symptoms'); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="symptoms">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
<textarea name="symptoms" class="form-control rich-editor" rows="2"></textarea>
</div>
<div class="mb-3">
<label class="form-label"><?php echo __('diagnosis'); ?></label>
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __('diagnosis'); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="diagnosis">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
<textarea name="diagnosis" class="form-control rich-editor" rows="2"></textarea>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __("treatment_plan"); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAIReport(this)">
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="treatment_plan">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
@ -1349,17 +1359,27 @@
</div>
<hr>
<div class="mb-3">
<label class="form-label"><?php echo __('symptoms'); ?></label>
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __('symptoms'); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="symptoms">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
<textarea name="symptoms" id="edit_visit_symptoms" class="form-control rich-editor" rows="2"></textarea>
</div>
<div class="mb-3">
<label class="form-label"><?php echo __('diagnosis'); ?></label>
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __('diagnosis'); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="diagnosis">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
<textarea name="diagnosis" id="edit_visit_diagnosis" class="form-control rich-editor" rows="2"></textarea>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center mb-2">
<label class="form-label mb-0"><?php echo __("treatment_plan"); ?></label>
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAIReport(this)">
<button type="button" class="btn btn-sm btn-outline-info" onclick="generateAISuggestion(this)" data-target="treatment_plan">
<i class="bi bi-stars"></i> AI Suggestion
</button>
</div>
@ -1821,8 +1841,8 @@
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.js"></script>
<script>
window.ALL_XRAYS_DATA = <?php echo json_encode($all_xrays, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE); ?>;
window.ALL_TESTS_DATA = <?php echo json_encode($all_tests, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE); ?>;
window.ALL_XRAYS_DATA = <?php echo json_encode($all_xrays, JSON_UNESCAPED_UNICODE); ?>;
window.ALL_TESTS_DATA = <?php echo json_encode($all_tests, JSON_UNESCAPED_UNICODE); ?>;
// Global error handler to help debugging
window.onerror = function(message, source, lineno, colno, error) {

View File

@ -40,7 +40,7 @@ $departments = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditDepartmentModal(<?php echo htmlspecialchars(json_encode($dept, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditDepartmentModal(<?php echo htmlspecialchars(json_encode($dept, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -100,7 +100,7 @@ $doctors = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditDoctorModal(<?php echo htmlspecialchars(json_encode($d, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditDoctorModal(<?php echo htmlspecialchars(json_encode($d, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -98,7 +98,7 @@ $employees = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditEmployeeModal(<?php echo htmlspecialchars(json_encode($emp, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditEmployeeModal(<?php echo htmlspecialchars(json_encode($emp, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -130,12 +130,12 @@ unset($inquiry);
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-dark py-1 px-2 border-end"
onclick="printInquiry(<?php echo htmlspecialchars(json_encode($inquiry, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="printInquiry(<?php echo htmlspecialchars(json_encode($inquiry, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('print'); ?>">
<i class="bi bi-printer"></i>
</button>
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditInquiryModal(<?php echo htmlspecialchars(json_encode($inquiry, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditInquiryModal(<?php echo htmlspecialchars(json_encode($inquiry, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -110,7 +110,7 @@ $tests = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditTestModal(<?php echo htmlspecialchars(json_encode($test, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditTestModal(<?php echo htmlspecialchars(json_encode($test, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -98,7 +98,7 @@ $nurses = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditNurseModal(<?php echo htmlspecialchars(json_encode($nurse, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditNurseModal(<?php echo htmlspecialchars(json_encode($nurse, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -94,7 +94,7 @@ $patients = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditPatientModal(<?php echo htmlspecialchars(json_encode($p, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditPatientModal(<?php echo htmlspecialchars(json_encode($p, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>
@ -104,12 +104,12 @@ $patients = $stmt->fetchAll();
<i class="bi bi-clipboard2-plus"></i>
</button>
<button class="btn btn-link text-success py-1 px-2 border-end"
onclick="showBillModal(null, <?php echo $p['id']; ?>, <?php echo htmlspecialchars(json_encode($p['name'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showBillModal(null, <?php echo $p['id']; ?>, <?php echo htmlspecialchars(json_encode($p['name'], JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('add_bill'); ?>">
<i class="bi bi-receipt"></i>
</button>
<button class="btn btn-link text-danger py-1 px-2"
onclick="showDeletePatientModal(<?php echo $p['id']; ?>, <?php echo htmlspecialchars(json_encode($p['name'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showDeletePatientModal(<?php echo $p['id']; ?>, <?php echo htmlspecialchars(json_encode($p['name'], JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
<i class="bi bi-trash3"></i>
</button>

View File

@ -71,7 +71,7 @@ $poisons = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditPoisonModal(<?php echo htmlspecialchars(json_encode($poison, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditPoisonModal(<?php echo htmlspecialchars(json_encode($poison, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -40,7 +40,7 @@ $groups = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditTestGroupModal(<?php echo htmlspecialchars(json_encode($group, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditTestGroupModal(<?php echo htmlspecialchars(json_encode($group, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -35,7 +35,6 @@ foreach ($raw_visits as $v) {
$v['lab_inquiries'] = $db->query("SELECT li.* FROM laboratory_inquiries li WHERE li.visit_id = " . (int)$v['id'])->fetchAll();
foreach($v['lab_inquiries'] as &$li) {
$li['items'] = $db->query("SELECT it.*, lt.name_$lang as test_name FROM inquiry_tests it JOIN laboratory_tests lt ON it.test_id = lt.id WHERE it.inquiry_id = " . (int)$li['id'])->fetchAll();
// Maintain a string summary for backward compatibility or simple display
$li['results'] = implode(', ', array_map(function($item) { return $item['test_name'] . ': ' . ($item['result'] ?: '-'); }, $li['items']));
}
@ -90,18 +89,21 @@ foreach ($raw_visits as $v) {
<table class="table table-hover align-middle mb-0">
<thead class="table-light text-secondary">
<tr>
<th class="px-4 py-3"><?php echo __('date'); ?></th>
<th class="px-4 py-3">#</th>
<th class="py-3"><?php echo __('date'); ?></th>
<th class="py-3"><?php echo __('patient'); ?></th>
<th class="py-3"><?php echo __('doctor'); ?></th>
<th class="py-3"><?php echo __('diagnosis'); ?></th>
<th class="py-3"><?php echo __('results'); ?></th>
<th class="py-3"><?php echo __('vitals'); ?></th>
<th class="py-3"><?php echo __('treatment'); ?></th>
<th class="py-3"><?php echo __('inquiries'); ?></th>
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
</tr>
</thead>
<tbody>
<?php if (empty($visits)): ?>
<tr>
<td colspan="6" class="text-center py-5 text-muted">
<td colspan="9" class="text-center py-5 text-muted">
<i class="bi bi-clipboard2-pulse display-4 d-block mb-3"></i>
No visits found.
</td>
@ -109,71 +111,83 @@ foreach ($raw_visits as $v) {
<?php else: ?>
<?php foreach ($visits as $v): ?>
<tr>
<td class="px-4 text-secondary"><?php echo date('Y-m-d H:i', strtotime($v['visit_date'])); ?></td>
<td class="fw-semibold text-dark"><?php echo htmlspecialchars($v['patient_name']); ?></td>
<td class="text-secondary"><?php echo htmlspecialchars($v['doctor_name']); ?></td>
<td class="px-4 text-muted small"><?php echo $v['id']; ?></td>
<td class="text-secondary"><?php echo date('Y-m-d H:i', strtotime($v['visit_date'])); ?></td>
<td class="fw-semibold text-dark"><?php echo htmlspecialchars($v['patient_name'] ?? ''); ?></td>
<td class="text-secondary"><?php echo htmlspecialchars($v['doctor_name'] ?? ''); ?></td>
<td>
<?php
$diagnosis_plain = strip_tags($v['diagnosis']);
$snippet = mb_strimwidth($diagnosis_plain, 0, 50, "...");
$diagnosis_plain = strip_tags($v['diagnosis'] ?? '');
$snippet = mb_strimwidth($diagnosis_plain, 0, 30, "...");
?>
<small class="text-muted" title="<?php echo htmlspecialchars($diagnosis_plain); ?>"><?php echo htmlspecialchars($snippet); ?></small>
</td>
<td>
<?php if (!empty($v['lab_inquiries'])): ?>
<span class="badge bg-info text-white me-1" title="<?php echo __('laboratory'); ?>" data-bs-toggle="tooltip">
<i class="bi bi-flask"></i> <?php echo count($v['lab_inquiries']); ?>
<?php
$lab_has_attachment = false;
foreach($v['lab_inquiries'] as $li) {
foreach($li['items'] as $item) {
if(!empty($item['attachment'])) $lab_has_attachment = true;
}
}
if($lab_has_attachment) echo ' <i class="bi bi-image"></i>';
$vitals = [];
if(!empty($v['blood_pressure'])) $vitals[] = '<i class="bi bi-heart-pulse me-1"></i>' . htmlspecialchars($v['blood_pressure'] ?? '');
if(!empty($v['weight'])) $vitals[] = '<i class="bi bi-speedometer2 me-1"></i>' . htmlspecialchars($v['weight'] ?? '') . 'kg';
if(!empty($v['temperature'])) $vitals[] = '<i class="bi bi-thermometer-half me-1"></i>' . htmlspecialchars($v['temperature'] ?? '') . '°C';
echo implode('<br>', $vitals);
?>
</td>
<td>
<?php
$treatment_plain = strip_tags($v['treatment_plan'] ?? '');
$t_snippet = mb_strimwidth($treatment_plain, 0, 30, "...");
?>
<small class="text-muted" title="<?php echo htmlspecialchars($treatment_plain); ?>"><?php echo htmlspecialchars($t_snippet); ?></small>
</td>
<td>
<div class="d-flex gap-1">
<?php if (!empty($v['lab_inquiries'])): ?>
<span class="badge bg-info text-white" title="<?php echo count($v['lab_inquiries']); ?> <?php echo __('laboratory'); ?>" data-bs-toggle="tooltip">
<i class="bi bi-flask"></i> <?php echo count($v['lab_inquiries']); ?>
</span>
<?php endif; ?>
<?php if (!empty($v['xray_inquiries'])): ?>
<span class="badge bg-dark text-white" title="<?php echo __('xray'); ?>" data-bs-toggle="tooltip">
<span class="badge bg-dark text-white" title="<?php echo count($v['xray_inquiries']); ?> <?php echo __('xray'); ?>" data-bs-toggle="tooltip">
<i class="bi bi-camera"></i> <?php echo count($v['xray_inquiries']); ?>
<?php
$has_attachment = false;
foreach($v['xray_inquiries'] as $xi) {
foreach($xi['items'] as $item) {
if(!empty($item['attachment'])) $has_attachment = true;
}
}
if($has_attachment) echo ' <i class="bi bi-image"></i>';
?>
</span>
<?php endif; ?>
</div>
</td>
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-success py-1 px-2 border-end" onclick="showVisitResultsModal(<?php echo htmlspecialchars(json_encode($v, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)" data-bs-toggle="tooltip" title="<?php echo __('view_results'); ?>"><i class="bi bi-eye"></i></button>
<button class="btn btn-link text-warning py-1 px-2 border-end"
onclick="showEditVisitModal(<?php echo htmlspecialchars(json_encode($v, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
<div class="d-flex justify-content-end gap-1">
<?php
// Encode safely for attribute
$json_v = htmlspecialchars(json_encode($v, JSON_UNESCAPED_UNICODE) ?: '{}', ENT_QUOTES, 'UTF-8');
$patient_name_json = htmlspecialchars(json_encode($v['patient_name'] ?? '', JSON_UNESCAPED_UNICODE) ?: '""', ENT_QUOTES, 'UTF-8');
?>
<button class="btn btn-sm btn-outline-success"
onclick="showVisitResultsModal(JSON.parse(this.getAttribute('data-visit')))"
data-visit="<?php echo $json_v; ?>"
data-bs-toggle="tooltip" title="<?php echo __('view_results'); ?>">
<i class="bi bi-eye"></i>
</button>
<button class="btn btn-sm btn-outline-warning"
onclick="showEditVisitModal(JSON.parse(this.getAttribute('data-visit')))"
data-visit="<?php echo $json_v; ?>"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>
<button class="btn btn-link text-info py-1 px-2 border-end"
onclick="showLabInquiryModalFromVisit(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo htmlspecialchars(json_encode($v['patient_name'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
<button class="btn btn-sm btn-outline-info"
onclick="showLabInquiryModalFromVisit(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo $patient_name_json; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('add_inquiry'); ?>">
<i class="bi bi-flask"></i>
</button>
<button class="btn btn-link text-dark py-1 px-2 border-end"
onclick="showXrayInquiryModalFromVisit(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo htmlspecialchars(json_encode($v['patient_name'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
<button class="btn btn-sm btn-outline-dark"
onclick="showXrayInquiryModalFromVisit(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo $patient_name_json; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('add_xray_inquiry'); ?>">
<i class="bi bi-camera"></i>
</button>
<button class="btn btn-link text-primary py-1 px-2 border-end"
<button class="btn btn-sm btn-outline-primary"
onclick="showReportModal(<?php echo $v['id']; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('new_report'); ?>">
<i class="bi bi-file-earmark-plus"></i>
</button>
<button class="btn btn-link text-success py-1 px-2"
onclick="showBillModal(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo htmlspecialchars(json_encode($v['patient_name'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
<button class="btn btn-sm btn-outline-success"
onclick="showBillModal(<?php echo $v['id']; ?>, <?php echo $v['patient_id']; ?>, <?php echo $patient_name_json; ?>)"
data-bs-toggle="tooltip" title="<?php echo __('create_bill'); ?>">
<i class="bi bi-receipt"></i>
</button>

View File

@ -40,7 +40,7 @@ $groups = $stmt->fetchAll();
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditXrayGroupModal(<?php echo htmlspecialchars(json_encode($group, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditXrayGroupModal(<?php echo htmlspecialchars(json_encode($group, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -143,12 +143,12 @@ $all_xrays_list = $db->query("SELECT id, name_$lang as name FROM xray_tests ORDE
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-info py-1 px-2 border-end"
onclick="printXrayInquiry(<?php echo htmlspecialchars(json_encode($inquiry, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="printXrayInquiry(<?php echo htmlspecialchars(json_encode($inquiry, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('print'); ?>">
<i class="bi bi-printer"></i>
</button>
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditXrayInquiryModal(<?php echo htmlspecialchars(json_encode($inquiry, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditXrayInquiryModal(<?php echo htmlspecialchars(json_encode($inquiry, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>

View File

@ -107,7 +107,7 @@ $all_xray_groups_list = $db->query("SELECT id, name_$lang as name FROM xray_grou
<td class="text-end px-4">
<div class="btn-group shadow-sm border rounded bg-white">
<button class="btn btn-link text-primary py-1 px-2 border-end"
onclick="showEditXrayTestModal(<?php echo htmlspecialchars(json_encode($test, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)); ?>)"
onclick="showEditXrayTestModal(<?php echo htmlspecialchars(json_encode($test, JSON_UNESCAPED_UNICODE)); ?>)"
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
<i class="bi bi-pencil-square"></i>
</button>