Autosave: 20260304-130505
This commit is contained in:
parent
933409e6cf
commit
6f43ba8047
184
api/appointments.php
Normal file
184
api/appointments.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../db/config.php';
|
||||
require_once __DIR__ . '/../helpers.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$db = db();
|
||||
$lang = $_SESSION['lang'] ?? 'en';
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
if ($method === 'GET') {
|
||||
$id = $_GET['id'] ?? null;
|
||||
if ($id) {
|
||||
// Fetch single appointment
|
||||
$stmt = $db->prepare("SELECT * FROM appointments WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$appointment = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
echo json_encode($appointment);
|
||||
exit;
|
||||
}
|
||||
|
||||
$startStr = $_GET['start'] ?? null;
|
||||
$endStr = $_GET['end'] ?? null;
|
||||
$doctor_id = $_GET['doctor_id'] ?? null;
|
||||
|
||||
$events = [];
|
||||
$businessHours = [];
|
||||
|
||||
// Fetch Appointments
|
||||
$query = "
|
||||
SELECT
|
||||
a.id, a.start_time as start, a.end_time as end, a.reason as title, a.status,
|
||||
a.patient_id, a.doctor_id,
|
||||
p.name as patient_name,
|
||||
d.name_$lang as doctor_name
|
||||
FROM appointments a
|
||||
JOIN patients p ON a.patient_id = p.id
|
||||
JOIN doctors d ON a.doctor_id = d.id
|
||||
WHERE 1=1";
|
||||
|
||||
$params = [];
|
||||
if ($startStr) { $query .= " AND a.start_time >= ?"; $params[] = $startStr; }
|
||||
if ($endStr) { $query .= " AND a.start_time <= ?"; $params[] = $endStr; }
|
||||
if ($doctor_id) { $query .= " AND a.doctor_id = ?"; $params[] = $doctor_id; }
|
||||
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$appointments = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($appointments as $a) {
|
||||
$color = '#0d6efd'; // blue
|
||||
if ($a['status'] === 'Completed') $color = '#198754'; // green
|
||||
if ($a['status'] === 'Cancelled') $color = '#dc3545'; // red
|
||||
|
||||
$events[] = [
|
||||
'id' => $a['id'],
|
||||
'title' => $a['patient_name'] . ' (' . $a['doctor_name'] . ')',
|
||||
'start' => $a['start'],
|
||||
'end' => $a['end'],
|
||||
'color' => $color,
|
||||
'extendedProps' => [
|
||||
'type' => 'appointment',
|
||||
'patient_id' => $a['patient_id'],
|
||||
'doctor_id' => $a['doctor_id'],
|
||||
'patient_name' => $a['patient_name'],
|
||||
'doctor_name' => $a['doctor_name'],
|
||||
'status' => $a['status'],
|
||||
'reason' => $a['reason']
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Fetch Holidays
|
||||
$holidayQuery = "SELECT holiday_date as start, name_$lang as title FROM holidays WHERE 1=1";
|
||||
$holidayParams = [];
|
||||
if ($startStr) { $holidayQuery .= " AND holiday_date >= ?"; $holidayParams[] = date('Y-m-d', strtotime($startStr)); }
|
||||
if ($endStr) { $holidayQuery .= " AND holiday_date <= ?"; $holidayParams[] = date('Y-m-d', strtotime($endStr)); }
|
||||
|
||||
$stmt = $db->prepare($holidayQuery);
|
||||
$stmt->execute($holidayParams);
|
||||
$holidays = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($holidays as $h) {
|
||||
$events[] = [
|
||||
'id' => 'hol_' . $h['start'],
|
||||
'title' => 'Holiday: ' . $h['title'],
|
||||
'start' => $h['start'],
|
||||
'allDay' => true,
|
||||
'color' => '#ffc107', // yellow
|
||||
'textColor' => '#000',
|
||||
'display' => 'background',
|
||||
'extendedProps' => ['type' => 'holiday']
|
||||
];
|
||||
|
||||
$events[] = [
|
||||
'title' => $h['title'],
|
||||
'start' => $h['start'],
|
||||
'allDay' => true,
|
||||
'color' => '#ffc107',
|
||||
'textColor' => '#000',
|
||||
'extendedProps' => ['type' => 'holiday']
|
||||
];
|
||||
}
|
||||
|
||||
// Fetch Doctor Business Hours
|
||||
if ($doctor_id) {
|
||||
$scheduleStmt = $db->prepare("SELECT day_of_week as day, start_time as start, end_time as end FROM doctor_schedules WHERE doctor_id = ?");
|
||||
$scheduleStmt->execute([$doctor_id]);
|
||||
$schedules = $scheduleStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$bhMap = [];
|
||||
foreach ($schedules as $s) {
|
||||
$key = $s['start'] . '-' . $s['end'];
|
||||
if (!isset($bhMap[$key])) {
|
||||
$bhMap[$key] = [
|
||||
'daysOfWeek' => [],
|
||||
'startTime' => $s['start'],
|
||||
'endTime' => $s['end']
|
||||
];
|
||||
}
|
||||
$bhMap[$key]['daysOfWeek'][] = (int)$s['day'];
|
||||
}
|
||||
$businessHours = array_values($bhMap);
|
||||
} else {
|
||||
$businessHours = [
|
||||
[
|
||||
'daysOfWeek' => [0, 1, 2, 3, 4, 5, 6],
|
||||
'startTime' => '08:00',
|
||||
'endTime' => '17:00'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'events' => $events,
|
||||
'businessHours' => $businessHours
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($method === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true) ?? $_POST;
|
||||
$action = $input['action'] ?? '';
|
||||
|
||||
if ($action === 'create') {
|
||||
$patient_id = $input['patient_id'] ?? '';
|
||||
$doctor_id = $input['doctor_id'] ?? '';
|
||||
$start_time = $input['start_time'] ?? '';
|
||||
$reason = $input['reason'] ?? '';
|
||||
|
||||
if ($patient_id && $doctor_id && $start_time) {
|
||||
$stmt = $db->prepare("INSERT INTO appointments (patient_id, doctor_id, start_time, end_time, reason) VALUES (?, ?, ?, DATE_ADD(?, INTERVAL 30 MINUTE), ?)");
|
||||
$stmt->execute([$patient_id, $doctor_id, $start_time, $start_time, $reason]);
|
||||
echo json_encode(['success' => true, 'id' => $db->lastInsertId()]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Missing fields']);
|
||||
}
|
||||
} elseif ($action === 'update') {
|
||||
$id = $input['id'] ?? '';
|
||||
$patient_id = $input['patient_id'] ?? '';
|
||||
$doctor_id = $input['doctor_id'] ?? '';
|
||||
$start_time = $input['start_time'] ?? '';
|
||||
$status = $input['status'] ?? 'Scheduled';
|
||||
$reason = $input['reason'] ?? '';
|
||||
|
||||
if ($id && $patient_id && $doctor_id && $start_time) {
|
||||
$stmt = $db->prepare("UPDATE appointments SET patient_id = ?, doctor_id = ?, start_time = ?, end_time = DATE_ADD(?, INTERVAL 30 MINUTE), status = ?, reason = ? WHERE id = ?");
|
||||
$stmt->execute([$patient_id, $doctor_id, $start_time, $start_time, $status, $reason, $id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Missing fields']);
|
||||
}
|
||||
} elseif ($action === 'delete') {
|
||||
$id = $input['id'] ?? '';
|
||||
if ($id) {
|
||||
$stmt = $db->prepare("DELETE FROM appointments WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Missing ID']);
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
12
appointments.php
Normal file
12
appointments.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
$section = 'appointments';
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
$db = db();
|
||||
$lang = $_SESSION['lang'] ?? 'en';
|
||||
|
||||
require_once __DIR__ . '/includes/actions.php';
|
||||
require_once __DIR__ . '/includes/common_data.php';
|
||||
require_once __DIR__ . '/includes/layout/header.php';
|
||||
require_once __DIR__ . '/includes/pages/appointments.php';
|
||||
require_once __DIR__ . '/includes/layout/footer.php';
|
||||
37
db/migrations/20260304_create_appointments_module.sql
Normal file
37
db/migrations/20260304_create_appointments_module.sql
Normal file
@ -0,0 +1,37 @@
|
||||
-- Create appointments table
|
||||
CREATE TABLE IF NOT EXISTS appointments (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
patient_id INT NOT NULL,
|
||||
doctor_id INT NOT NULL,
|
||||
start_time DATETIME NOT NULL,
|
||||
end_time DATETIME NOT NULL,
|
||||
status ENUM('Scheduled', 'Completed', 'Cancelled') DEFAULT 'Scheduled',
|
||||
reason TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (patient_id) REFERENCES patients(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (doctor_id) REFERENCES doctors(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create holidays table
|
||||
CREATE TABLE IF NOT EXISTS holidays (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
holiday_date DATE NOT NULL,
|
||||
name_en VARCHAR(255) NOT NULL,
|
||||
name_ar VARCHAR(255) NOT NULL,
|
||||
is_recurring BOOLEAN DEFAULT FALSE
|
||||
);
|
||||
|
||||
-- Create doctor schedules table (working hours)
|
||||
CREATE TABLE IF NOT EXISTS doctor_schedules (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
doctor_id INT NOT NULL,
|
||||
day_of_week INT NOT NULL, -- 0 (Sunday) to 6 (Saturday)
|
||||
start_time TIME NOT NULL,
|
||||
end_time TIME NOT NULL,
|
||||
FOREIGN KEY (doctor_id) REFERENCES doctors(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Seed some holidays
|
||||
INSERT INTO holidays (holiday_date, name_en, name_ar, is_recurring) VALUES
|
||||
('2026-01-01', 'New Year', 'رأس السنة', TRUE),
|
||||
('2026-12-25', 'Christmas', 'عيد الميلاد', TRUE);
|
||||
38
db/migrations/20260304_create_xray_module.sql
Normal file
38
db/migrations/20260304_create_xray_module.sql
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
-- X-Ray Module Tables
|
||||
CREATE TABLE IF NOT EXISTS xray_groups (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name_en VARCHAR(255) NOT NULL,
|
||||
name_ar VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS xray_tests (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
group_id INT,
|
||||
name_en VARCHAR(255) NOT NULL,
|
||||
name_ar VARCHAR(255) NOT NULL,
|
||||
price DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (group_id) REFERENCES xray_groups(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS xray_inquiries (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
patient_name VARCHAR(255) NOT NULL,
|
||||
inquiry_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
source ENUM('Internal', 'External') DEFAULT 'Internal',
|
||||
status ENUM('Pending', 'Completed', 'Cancelled') DEFAULT 'Pending',
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS xray_inquiry_items (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
inquiry_id INT NOT NULL,
|
||||
xray_id INT NOT NULL,
|
||||
result TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (inquiry_id) REFERENCES xray_inquiries(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (xray_id) REFERENCES xray_tests(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
49
db/migrations/20260304_seed_xray_data.sql
Normal file
49
db/migrations/20260304_seed_xray_data.sql
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
-- Seed X-Ray Groups
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Chest', 'الصدر');
|
||||
SET @chest_id = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Extremities', 'الأطراف');
|
||||
SET @ext_id = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Spine', 'العمود الفقري');
|
||||
SET @spine_id = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Abdomen', 'البطن');
|
||||
SET @abd_id = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Dental', 'الأسنان');
|
||||
SET @den_id = LAST_INSERT_ID();
|
||||
|
||||
INSERT INTO xray_groups (name_en, name_ar) VALUES ('Skull', 'الجمجمة');
|
||||
SET @skl_id = LAST_INSERT_ID();
|
||||
|
||||
-- Seed X-Ray Tests
|
||||
-- Chest
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@chest_id, 'Chest PA/Lateral', 'أشعة على الصدر - وضع أمامي جانبي', 150.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@chest_id, 'Chest PA Only', 'أشعة على الصدر - وضع أمامي خلفي فقط', 100.00);
|
||||
|
||||
-- Extremities
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Hand AP/Lateral', 'أشعة على اليد', 120.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Foot AP/Lateral', 'أشعة على القدم', 120.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Knee AP/Lateral', 'أشعة على الركبة', 140.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Shoulder AP/Lateral', 'أشعة على الكتف', 150.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Elbow AP/Lateral', 'أشعة على الكوع', 120.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@ext_id, 'Ankle AP/Lateral', 'أشعة على الكاحل', 120.00);
|
||||
|
||||
-- Spine
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@spine_id, 'Cervical Spine AP/Lateral', 'أشعة على الفقرات العنقية', 180.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@spine_id, 'Lumbar Spine AP/Lateral', 'أشعة على الفقرات القطنية', 200.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@spine_id, 'Thoracic Spine AP/Lateral', 'أشعة على الفقرات الصدرية', 180.00);
|
||||
|
||||
-- Abdomen
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@abd_id, 'Abdomen KUB', 'أشعة على البطن والمسالك البولية', 160.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@abd_id, 'Abdomen Erect/Supine', 'أشعة على البطن', 160.00);
|
||||
|
||||
-- Dental
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@den_id, 'Dental Panoramic', 'أشعة بانوراما للأسنان', 250.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@den_id, 'Periapical X-Ray', 'أشعة صغيرة للأسنان', 50.00);
|
||||
|
||||
-- Skull
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@skl_id, 'Skull AP/Lateral', 'أشعة على الجمجمة', 180.00);
|
||||
INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (@skl_id, 'Paranasal Sinuses', 'أشعة على الجيوب الأنفية', 150.00);
|
||||
@ -156,8 +156,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$reason = $_POST['reason'] ?? '';
|
||||
|
||||
if ($patient_id && $doctor_id && $date) {
|
||||
$stmt = $db->prepare("INSERT INTO appointments (patient_id, doctor_id, appointment_date, reason) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$patient_id, $doctor_id, $date, $reason]);
|
||||
$stmt = $db->prepare("INSERT INTO appointments (patient_id, doctor_id, start_time, end_time, reason) VALUES (?, ?, ?, DATE_ADD(?, INTERVAL 30 MINUTE), ?)");
|
||||
$stmt->execute([$patient_id, $doctor_id, $date, $date, $reason]);
|
||||
$_SESSION['flash_message'] = __('book_appointment') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
@ -401,7 +401,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$patient_name = $_POST['patient_name'] ?? '';
|
||||
$test_ids = $_POST['test_ids'] ?? [];
|
||||
$results = $_POST['results'] ?? [];
|
||||
$ranges = $_POST['normal_ranges'] ?? [];
|
||||
$source = $_POST['source'] ?? 'Internal';
|
||||
$date = $_POST['inquiry_date'] ?: date('Y-m-d H:i');
|
||||
$status = $_POST['status'] ?? 'Pending';
|
||||
@ -414,10 +413,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$inquiry_id = $db->lastInsertId();
|
||||
|
||||
if (!empty($test_ids)) {
|
||||
$testStmt = $db->prepare("INSERT INTO inquiry_tests (inquiry_id, test_id, result, normal_range) VALUES (?, ?, ?, ?)");
|
||||
$testStmt = $db->prepare("INSERT INTO inquiry_tests (inquiry_id, test_id, result) VALUES (?, ?, ?)");
|
||||
foreach ($test_ids as $index => $tid) {
|
||||
if ($tid) {
|
||||
$testStmt->execute([$inquiry_id, $tid, $results[$index] ?? '', $ranges[$index] ?? '']);
|
||||
$testStmt->execute([$inquiry_id, $tid, $results[$index] ?? '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,7 +429,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$patient_name = $_POST['patient_name'] ?? '';
|
||||
$test_ids = $_POST['test_ids'] ?? [];
|
||||
$results = $_POST['results'] ?? [];
|
||||
$ranges = $_POST['normal_ranges'] ?? [];
|
||||
$source = $_POST['source'] ?? 'Internal';
|
||||
$date = $_POST['inquiry_date'] ?: date('Y-m-d H:i');
|
||||
$status = $_POST['status'] ?? 'Pending';
|
||||
@ -446,10 +444,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$stmt->execute([$id]);
|
||||
|
||||
if (!empty($test_ids)) {
|
||||
$testStmt = $db->prepare("INSERT INTO inquiry_tests (inquiry_id, test_id, result, normal_range) VALUES (?, ?, ?, ?)");
|
||||
$testStmt = $db->prepare("INSERT INTO inquiry_tests (inquiry_id, test_id, result) VALUES (?, ?, ?)");
|
||||
foreach ($test_ids as $index => $tid) {
|
||||
if ($tid) {
|
||||
$testStmt->execute([$id, $tid, $results[$index] ?? '', $ranges[$index] ?? '']);
|
||||
$testStmt->execute([$id, $tid, $results[$index] ?? '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -465,6 +463,124 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'add_xray_group') {
|
||||
$name_en = $_POST['name_en'] ?? '';
|
||||
$name_ar = $_POST['name_ar'] ?? '';
|
||||
if ($name_en && $name_ar) {
|
||||
$stmt = $db->prepare("INSERT INTO xray_groups (name_en, name_ar) VALUES (?, ?)");
|
||||
$stmt->execute([$name_en, $name_ar]);
|
||||
$_SESSION['flash_message'] = __('add_xray_group') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'edit_xray_group') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
$name_en = $_POST['name_en'] ?? '';
|
||||
$name_ar = $_POST['name_ar'] ?? '';
|
||||
if ($id && $name_en && $name_ar) {
|
||||
$stmt = $db->prepare("UPDATE xray_groups SET name_en = ?, name_ar = ? WHERE id = ?");
|
||||
$stmt->execute([$name_en, $name_ar, $id]);
|
||||
$_SESSION['flash_message'] = __('edit_xray_group') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'delete_xray_group') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
if ($id) {
|
||||
$stmt = $db->prepare("DELETE FROM xray_groups WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'add_xray_test') {
|
||||
$group_id = $_POST['group_id'] ?: null;
|
||||
$name_en = $_POST['name_en'] ?? '';
|
||||
$name_ar = $_POST['name_ar'] ?? '';
|
||||
$price = $_POST['price'] ?? 0;
|
||||
if ($name_en && $name_ar) {
|
||||
$stmt = $db->prepare("INSERT INTO xray_tests (group_id, name_en, name_ar, price) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$group_id, $name_en, $name_ar, $price]);
|
||||
$_SESSION['flash_message'] = __('add_xray_test') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'edit_xray_test') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
$group_id = $_POST['group_id'] ?: null;
|
||||
$name_en = $_POST['name_en'] ?? '';
|
||||
$name_ar = $_POST['name_ar'] ?? '';
|
||||
$price = $_POST['price'] ?? 0;
|
||||
if ($id && $name_en && $name_ar) {
|
||||
$stmt = $db->prepare("UPDATE xray_tests SET group_id = ?, name_en = ?, name_ar = ?, price = ? WHERE id = ?");
|
||||
$stmt->execute([$group_id, $name_en, $name_ar, $price, $id]);
|
||||
$_SESSION['flash_message'] = __('edit_xray_test') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'delete_xray_test') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
if ($id) {
|
||||
$stmt = $db->prepare("DELETE FROM xray_tests WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'add_xray_inquiry') {
|
||||
$patient_name = $_POST['patient_name'] ?? '';
|
||||
$xray_ids = $_POST['xray_ids'] ?? [];
|
||||
$results = $_POST['results'] ?? [];
|
||||
$source = $_POST['source'] ?? 'Internal';
|
||||
$date = $_POST['inquiry_date'] ?: date('Y-m-d H:i');
|
||||
$status = $_POST['status'] ?? 'Pending';
|
||||
$notes = $_POST['notes'] ?? '';
|
||||
if ($patient_name) {
|
||||
$db->beginTransaction();
|
||||
$stmt = $db->prepare("INSERT INTO xray_inquiries (patient_name, source, inquiry_date, status, notes) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$patient_name, $source, $date, $status, $notes]);
|
||||
$inquiry_id = $db->lastInsertId();
|
||||
if (!empty($xray_ids)) {
|
||||
$testStmt = $db->prepare("INSERT INTO xray_inquiry_items (inquiry_id, xray_id, result) VALUES (?, ?, ?)");
|
||||
foreach ($xray_ids as $index => $tid) {
|
||||
if ($tid) {
|
||||
$testStmt->execute([$inquiry_id, $tid, $results[$index] ?? '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->commit();
|
||||
$_SESSION['flash_message'] = __('add_xray_inquiry') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'edit_xray_inquiry') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
$patient_name = $_POST['patient_name'] ?? '';
|
||||
$xray_ids = $_POST['xray_ids'] ?? [];
|
||||
$results = $_POST['results'] ?? [];
|
||||
$source = $_POST['source'] ?? 'Internal';
|
||||
$date = $_POST['inquiry_date'] ?: date('Y-m-d H:i');
|
||||
$status = $_POST['status'] ?? 'Pending';
|
||||
$notes = $_POST['notes'] ?? '';
|
||||
if ($id && $patient_name) {
|
||||
$db->beginTransaction();
|
||||
$stmt = $db->prepare("UPDATE xray_inquiries SET patient_name = ?, source = ?, inquiry_date = ?, status = ?, notes = ? WHERE id = ?");
|
||||
$stmt->execute([$patient_name, $source, $date, $status, $notes, $id]);
|
||||
$stmt = $db->prepare("DELETE FROM xray_inquiry_items WHERE inquiry_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
if (!empty($xray_ids)) {
|
||||
$testStmt = $db->prepare("INSERT INTO xray_inquiry_items (inquiry_id, xray_id, result) VALUES (?, ?, ?)");
|
||||
foreach ($xray_ids as $index => $tid) {
|
||||
if ($tid) {
|
||||
$testStmt->execute([$id, $tid, $results[$index] ?? '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->commit();
|
||||
$_SESSION['flash_message'] = __('edit_xray_inquiry') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
} elseif ($_POST['action'] === 'delete_xray_inquiry') {
|
||||
$id = $_POST['id'] ?? '';
|
||||
if ($id) {
|
||||
$stmt = $db->prepare("DELETE FROM xray_inquiries WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$_SESSION['flash_message'] = __('delete') . ' ' . __('successfully');
|
||||
$redirect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,11 +8,15 @@ $all_employees = $db->query("SELECT id, name_$lang as name FROM employees")->fet
|
||||
$all_poisons = $db->query("SELECT id, name_$lang as name FROM poisons")->fetchAll();
|
||||
$all_insurance = $db->query("SELECT id, name_$lang as name FROM insurance_companies")->fetchAll();
|
||||
$all_test_groups = $db->query("SELECT id, name_$lang as name FROM test_groups")->fetchAll();
|
||||
$all_tests = $db->query("SELECT id, name_$lang as name, price FROM laboratory_tests")->fetchAll();
|
||||
$all_tests = $db->query("SELECT id, name_$lang as name, price, normal_range FROM laboratory_tests")->fetchAll();
|
||||
|
||||
// X-Ray Data
|
||||
$all_xray_groups = $db->query("SELECT id, name_$lang as name FROM xray_groups")->fetchAll();
|
||||
$all_xrays = $db->query("SELECT id, name_$lang as name, price FROM xray_tests")->fetchAll();
|
||||
|
||||
$scheduled_appointments = $db->query("
|
||||
SELECT a.id, p.name as patient_name, a.appointment_date, a.patient_id, a.doctor_id
|
||||
SELECT a.id, p.name as patient_name, a.start_time, a.patient_id, a.doctor_id
|
||||
FROM appointments a
|
||||
JOIN patients p ON a.patient_id = p.id
|
||||
WHERE a.status = 'Scheduled'
|
||||
ORDER BY a.appointment_date ASC")->fetchAll();
|
||||
ORDER BY a.start_time ASC")->fetchAll();
|
||||
@ -1236,7 +1236,7 @@
|
||||
<option value=""><?php echo __('search'); ?>...</option>
|
||||
<?php foreach ($scheduled_appointments as $sa): ?>
|
||||
<option value="<?php echo $sa['id']; ?>" data-patient="<?php echo $sa['patient_id']; ?>" data-doctor="<?php echo $sa['doctor_id']; ?>">
|
||||
<?php echo htmlspecialchars($sa['patient_name']); ?> - <?php echo $sa['appointment_date']; ?>
|
||||
<?php echo htmlspecialchars($sa['patient_name']); ?> - <?php echo $sa['start_time']; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
@ -1455,12 +1455,352 @@
|
||||
</div>
|
||||
|
||||
<!-- jQuery (Required for Select2) -->
|
||||
|
||||
<!-- X-Ray Group Modals -->
|
||||
<div class="modal fade" id="addXrayGroupModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="add_xray_group">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('add_xray_group'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_en'); ?></label>
|
||||
<input type="text" name="name_en" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_ar'); ?></label>
|
||||
<input type="text" name="name_ar" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="editXrayGroupModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="edit_xray_group">
|
||||
<input type="hidden" name="id" id="edit_xray_group_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('edit_xray_group'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_en'); ?></label>
|
||||
<input type="text" name="name_en" id="edit_xray_group_name_en" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_ar'); ?></label>
|
||||
<input type="text" name="name_ar" id="edit_xray_group_name_ar" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="deleteXrayGroupModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="delete_xray_group">
|
||||
<input type="hidden" name="id" id="delete_xray_group_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('delete'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center py-4">
|
||||
<i class="bi bi-exclamation-triangle text-danger display-4 d-block mb-3"></i>
|
||||
<p class="mb-0 fs-5"><?php echo __('confirm_delete'); ?>?</p>
|
||||
<p class="text-muted small"><?php echo __('this_action_cannot_be_undone'); ?></p>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-danger px-4"><?php echo __('delete'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- X-Ray Test Modals -->
|
||||
<div class="modal fade" id="addXrayTestModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="add_xray_test">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('add_xray_test'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_en'); ?></label>
|
||||
<input type="text" name="name_en" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_ar'); ?></label>
|
||||
<input type="text" name="name_ar" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('xray_group'); ?></label>
|
||||
<select name="group_id" class="form-select" required>
|
||||
<option value=""><?php echo __('select'); ?>...</option>
|
||||
<?php foreach ($all_xray_groups as $group): ?>
|
||||
<option value="<?php echo $group['id']; ?>"><?php echo htmlspecialchars($group['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('price'); ?></label>
|
||||
<input type="number" step="0.01" name="price" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="editXrayTestModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="edit_xray_test">
|
||||
<input type="hidden" name="id" id="edit_xray_test_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('edit_xray_test'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_en'); ?></label>
|
||||
<input type="text" name="name_en" id="edit_xray_test_name_en" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('name_ar'); ?></label>
|
||||
<input type="text" name="name_ar" id="edit_xray_test_name_ar" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('xray_group'); ?></label>
|
||||
<select name="group_id" id="edit_xray_test_group_id" class="form-select" required>
|
||||
<option value=""><?php echo __('select'); ?>...</option>
|
||||
<?php foreach ($all_xray_groups as $group): ?>
|
||||
<option value="<?php echo $group['id']; ?>"><?php echo htmlspecialchars($group['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('price'); ?></label>
|
||||
<input type="number" step="0.01" name="price" id="edit_xray_test_price" class="form-control" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="deleteXrayTestModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="delete_xray_test">
|
||||
<input type="hidden" name="id" id="delete_xray_test_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('delete'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center py-4">
|
||||
<i class="bi bi-exclamation-triangle text-danger display-4 d-block mb-3"></i>
|
||||
<p class="mb-0 fs-5"><?php echo __('confirm_delete'); ?>?</p>
|
||||
<p class="text-muted small"><?php echo __('this_action_cannot_be_undone'); ?></p>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-danger px-4"><?php echo __('delete'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- X-Ray Inquiry Modals -->
|
||||
<div class="modal fade" id="addXrayInquiryModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="add_xray_inquiry">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('add_xray_inquiry'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('patient'); ?></label>
|
||||
<input type="text" name="patient_name" class="form-control" required placeholder="<?php echo __('name'); ?>">
|
||||
</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 __('xrays'); ?></label>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addXrayInquiryRow('add')">
|
||||
<i class="bi bi-plus-circle"></i> <?php echo __('add_xray'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="add_xray_inquiry_items_container">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label"><?php echo __('source'); ?></label>
|
||||
<select name="source" class="form-select">
|
||||
<option value="Internal"><?php echo __('internal'); ?></option>
|
||||
<option value="External"><?php echo __('external'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label"><?php echo __('status'); ?></label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="Pending"><?php echo __('Pending'); ?></option>
|
||||
<option value="Completed"><?php echo __('Completed'); ?></option>
|
||||
<option value="Cancelled"><?php echo __('Cancelled'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('inquiry_date'); ?></label>
|
||||
<input type="datetime-local" name="inquiry_date" class="form-control" value="<?php echo date('Y-m-d\TH:i'); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('notes'); ?></label>
|
||||
<textarea name="notes" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="editXrayInquiryModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="edit_xray_inquiry">
|
||||
<input type="hidden" name="id" id="edit_xray_inquiry_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-primary text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('edit_xray_inquiry'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('patient'); ?></label>
|
||||
<input type="text" name="patient_name" id="edit_xray_inquiry_patient_name" class="form-control" required placeholder="<?php echo __('name'); ?>">
|
||||
</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 __('xrays'); ?></label>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addXrayInquiryRow('edit')">
|
||||
<i class="bi bi-plus-circle"></i> <?php echo __('add_xray'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="edit_xray_inquiry_items_container">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label"><?php echo __('source'); ?></label>
|
||||
<select name="source" id="edit_xray_inquiry_source" class="form-select">
|
||||
<option value="Internal"><?php echo __('internal'); ?></option>
|
||||
<option value="External"><?php echo __('external'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label"><?php echo __('status'); ?></label>
|
||||
<select name="status" id="edit_xray_inquiry_status" class="form-select">
|
||||
<option value="Pending"><?php echo __('Pending'); ?></option>
|
||||
<option value="Completed"><?php echo __('Completed'); ?></option>
|
||||
<option value="Cancelled"><?php echo __('Cancelled'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('inquiry_date'); ?></label>
|
||||
<input type="datetime-local" name="inquiry_date" id="edit_xray_inquiry_date" class="form-control">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?php echo __('notes'); ?></label>
|
||||
<textarea name="notes" id="edit_xray_inquiry_notes" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-primary px-4"><?php echo __('save'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="deleteXrayInquiryModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<form action="<?php echo $_SERVER['PHP_SELF']; ?>?section=<?php echo $section; ?>" method="POST">
|
||||
<input type="hidden" name="action" value="delete_xray_inquiry">
|
||||
<input type="hidden" name="id" id="delete_xray_inquiry_id">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title fw-bold"><?php echo __('delete'); ?></h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center py-4">
|
||||
<i class="bi bi-exclamation-triangle text-danger display-4 d-block mb-3"></i>
|
||||
<p class="mb-0 fs-5"><?php echo __('confirm_delete'); ?>?</p>
|
||||
<p class="text-muted small"><?php echo __('this_action_cannot_be_undone'); ?></p>
|
||||
</div>
|
||||
<div class="modal-footer bg-light">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="submit" class="btn btn-danger px-4"><?php echo __('delete'); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<!-- Select2 JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<!-- Bootstrap 5 Bundle JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.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); ?>;
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Global error handler to help debugging
|
||||
window.onerror = function(message, source, lineno, colno, error) {
|
||||
@ -2005,6 +2345,195 @@
|
||||
} catch (e) { console.error('Print inquiry failed:', e); }
|
||||
}
|
||||
|
||||
function showEditXrayGroupModal(group) {
|
||||
if (!group) return;
|
||||
var el = document.getElementById('editXrayGroupModal');
|
||||
if (el) {
|
||||
var fields = {
|
||||
'edit_xray_group_id': group.id,
|
||||
'edit_xray_group_name_en': group.name_en,
|
||||
'edit_xray_group_name_ar': group.name_ar
|
||||
};
|
||||
for (var id in fields) {
|
||||
var field = document.getElementById(id);
|
||||
if (field) field.value = fields[id];
|
||||
}
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function showDeleteXrayGroupModal(id) {
|
||||
var el = document.getElementById('deleteXrayGroupModal');
|
||||
if (el) {
|
||||
var field = document.getElementById('delete_xray_group_id');
|
||||
if (field) field.value = id || '';
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function showEditXrayTestModal(test) {
|
||||
if (!test) return;
|
||||
var el = document.getElementById('editXrayTestModal');
|
||||
if (el) {
|
||||
var fields = {
|
||||
'edit_xray_test_id': test.id,
|
||||
'edit_xray_test_name_en': test.name_en,
|
||||
'edit_xray_test_name_ar': test.name_ar,
|
||||
'edit_xray_test_group_id': test.group_id || '',
|
||||
'edit_xray_test_price': test.price || '0.00'
|
||||
};
|
||||
for (var id in fields) {
|
||||
var field = document.getElementById(id);
|
||||
if (field) field.value = fields[id];
|
||||
}
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function showDeleteXrayTestModal(id) {
|
||||
var el = document.getElementById('deleteXrayTestModal');
|
||||
if (el) {
|
||||
var field = document.getElementById('delete_xray_test_id');
|
||||
if (field) field.value = id || '';
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function addXrayInquiryRow(type, data = null) {
|
||||
const container = document.getElementById(type + '_xray_inquiry_items_container');
|
||||
if (!container) return;
|
||||
const row = document.createElement('div');
|
||||
row.className = 'test-row card bg-light border-0 mb-2 p-2';
|
||||
let options = `<option value=""><?php echo __('search'); ?>...</option>`;
|
||||
if (typeof window.ALL_XRAYS_DATA !== 'undefined') {
|
||||
window.ALL_XRAYS_DATA.forEach(x => {
|
||||
const selected = data && data.xray_id == x.id ? 'selected' : '';
|
||||
options += `<option value="${x.id}" ${selected}>${x.name}</option>`;
|
||||
});
|
||||
}
|
||||
row.innerHTML = `
|
||||
<div class="row g-2">
|
||||
<div class="col-md-11">
|
||||
<div class="row g-2">
|
||||
<div class="col-md-12 mb-2">
|
||||
<select name="xray_ids[]" class="form-select select2-test" required>
|
||||
${options}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<textarea name="results[]" class="form-control form-control-sm" rows="2" placeholder="<?php echo __('result'); ?>">${data ? (data.result || '') : ''}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-center justify-content-center">
|
||||
<button type="button" class="btn btn-link text-danger p-0" onclick="this.closest('.test-row').remove()">
|
||||
<i class="bi bi-x-circle fs-5"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(row);
|
||||
initSelect2();
|
||||
}
|
||||
|
||||
function showEditXrayInquiryModal(inquiry) {
|
||||
if (!inquiry) return;
|
||||
var el = document.getElementById('editXrayInquiryModal');
|
||||
if (el) {
|
||||
var fields = {
|
||||
'edit_xray_inquiry_id': inquiry.id || '',
|
||||
'edit_xray_inquiry_patient_name': inquiry.patient_name || '',
|
||||
'edit_xray_inquiry_source': inquiry.source || 'Internal',
|
||||
'edit_xray_inquiry_status': inquiry.status || 'Pending',
|
||||
'edit_xray_inquiry_notes': inquiry.notes || ''
|
||||
};
|
||||
for (var id in fields) {
|
||||
var field = document.getElementById(id);
|
||||
if (field) field.value = fields[id];
|
||||
}
|
||||
if (inquiry.inquiry_date) {
|
||||
var dateField = document.getElementById('edit_xray_inquiry_date');
|
||||
if (dateField) dateField.value = inquiry.inquiry_date.replace(' ', 'T').substring(0, 16);
|
||||
}
|
||||
const container = document.getElementById('edit_xray_inquiry_items_container');
|
||||
if (container) {
|
||||
container.innerHTML = '';
|
||||
if (inquiry.items && inquiry.items.length > 0) {
|
||||
inquiry.items.forEach(item => {
|
||||
addXrayInquiryRow('edit', item);
|
||||
});
|
||||
} else {
|
||||
addXrayInquiryRow('edit');
|
||||
}
|
||||
}
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function showDeleteXrayInquiryModal(id) {
|
||||
var el = document.getElementById('deleteXrayInquiryModal');
|
||||
if (el) {
|
||||
var field = document.getElementById('delete_xray_inquiry_id');
|
||||
if (field) field.value = id || '';
|
||||
bootstrap.Modal.getOrCreateInstance(el).show();
|
||||
}
|
||||
}
|
||||
|
||||
function printXrayInquiry(inquiry) {
|
||||
if (!inquiry) return;
|
||||
try {
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (!printWindow) return;
|
||||
const date = inquiry.inquiry_date ? new Date(inquiry.inquiry_date).toLocaleString() : '';
|
||||
let itemsHtml = '';
|
||||
if (inquiry.items && inquiry.items.length > 0) {
|
||||
inquiry.items.forEach(i => {
|
||||
itemsHtml += `
|
||||
<div style="margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 10px;">
|
||||
<h3 style="color: #002D62; margin-bottom: 5px;">${i.xray_name}</h3>
|
||||
<div style="white-space: pre-wrap;">${i.result || 'No result recorded'}</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
printWindow.document.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>X-Ray Report - ${inquiry.patient_name}</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #333; line-height: 1.6; padding: 20px; }
|
||||
.header { text-align: center; border-bottom: 2px solid #002D62; padding-bottom: 20px; margin-bottom: 30px; }
|
||||
.header h1 { margin: 0; color: #002D62; }
|
||||
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }
|
||||
.info-item b { color: #555; }
|
||||
.footer { margin-top: 50px; border-top: 1px solid #eee; padding-top: 20px; text-align: center; font-size: 0.9em; color: #777; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>X-RAY REPORT</h1>
|
||||
<p>Hospital Management System</p>
|
||||
</div>
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><b>Patient Name:</b> ${inquiry.patient_name}</div>
|
||||
<div class="info-item"><b>Date:</b> ${date}</div>
|
||||
<div class="info-item"><b>Inquiry ID:</b> #${inquiry.id}</div>
|
||||
<div class="info-item"><b>Status:</b> ${inquiry.status}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
${itemsHtml}
|
||||
</div>
|
||||
${inquiry.notes ? `<div style="margin-top: 20px; border-top: 1px solid #eee; padding-top: 10px;"><b>Notes:</b><p>${inquiry.notes}</p></div>` : ""}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
printWindow.document.close();
|
||||
printWindow.print();
|
||||
} catch (e) {
|
||||
console.error('Printing failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
function addBillItem() {
|
||||
const container = document.getElementById('bill_items_container');
|
||||
if (!container) return;
|
||||
|
||||
@ -70,6 +70,7 @@ $message = $message ?? '';
|
||||
<a href="dashboard.php" class="sidebar-link <?php echo $section === 'dashboard' ? 'active' : ''; ?>"><i class="bi bi-speedometer2 me-2"></i> <?php echo __('dashboard'); ?></a>
|
||||
<a href="patients.php" class="sidebar-link <?php echo $section === 'patients' ? 'active' : ''; ?>"><i class="bi bi-people me-2"></i> <?php echo __('patients'); ?></a>
|
||||
<a href="visits.php" class="sidebar-link <?php echo $section === 'visits' ? 'active' : ''; ?>"><i class="bi bi-clipboard2-pulse me-2"></i> <?php echo __('visits'); ?></a>
|
||||
<a href="appointments.php" class="sidebar-link <?php echo $section === "appointments" ? "active" : ""; ?>"><i class="bi bi-calendar-event me-2"></i> <?php echo __("appointments"); ?></a>
|
||||
|
||||
<a href="#labSubmenu" data-bs-toggle="collapse" class="sidebar-link <?php echo in_array($section, ['laboratory_tests', 'test_groups', 'laboratory_inquiries']) ? 'active' : ''; ?> d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-prescription2 me-2"></i> <?php echo __('laboratory'); ?></span>
|
||||
@ -83,6 +84,19 @@ $message = $message ?? '';
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- X-Ray Module -->
|
||||
<a href="#xraySubmenu" data-bs-toggle="collapse" class="sidebar-link <?php echo in_array($section, ['xray_tests', 'xray_groups', 'xray_inquiries']) ? 'active' : ''; ?> d-flex justify-content-between align-items-center">
|
||||
<span><i class="bi bi-x-diamond me-2"></i> <?php echo __('xray'); ?></span>
|
||||
<i class="bi bi-chevron-down small"></i>
|
||||
</a>
|
||||
<div class="collapse <?php echo in_array($section, ['xray_tests', 'xray_groups', 'xray_inquiries']) ? 'show' : ''; ?>" id="xraySubmenu">
|
||||
<div class="sidebar-submenu">
|
||||
<a href="xray_tests.php" class="sidebar-link py-2 <?php echo $section === 'xray_tests' ? 'active' : ''; ?>"><i class="bi bi-list-check me-2"></i> <?php echo __('tests'); ?></a>
|
||||
<a href="xray_groups.php" class="sidebar-link py-2 <?php echo $section === 'xray_groups' ? 'active' : ''; ?>"><i class="bi bi-collection me-2"></i> <?php echo __('groups'); ?></a>
|
||||
<a href="xray_inquiries.php" class="sidebar-link py-2 <?php echo $section === 'xray_inquiries' ? 'active' : ''; ?>"><i class="bi bi-question-circle me-2"></i> <?php echo __('inquiries'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="billing.php" class="sidebar-link <?php echo $section === 'billing' ? 'active' : ''; ?>"><i class="bi bi-receipt me-2"></i> <?php echo __('billing'); ?></a>
|
||||
<a href="insurance.php" class="sidebar-link <?php echo $section === 'insurance' ? 'active' : ''; ?>"><i class="bi bi-shield-check me-2"></i> <?php echo __('insurance'); ?></a>
|
||||
<a href="doctors.php" class="sidebar-link <?php echo $section === 'doctors' ? 'active' : ''; ?>"><i class="bi bi-person-badge me-2"></i> <?php echo __('doctors'); ?></a>
|
||||
@ -116,7 +130,7 @@ $message = $message ?? '';
|
||||
<i class="bi bi-translate"></i> <?php echo get_lang_name(); ?>
|
||||
</a>
|
||||
<div class="dropdown">
|
||||
<a class="nav-link dropdown-toggle d-flex align-items-center" href="#" role="button" data-bs-toggle="dropdown">
|
||||
<a class="nav-link dropdown-toggle d-flex align-items-center" href="#" role="button" data-bs-dropdown="dropdown">
|
||||
<img src="https://ui-avatars.com/api/?name=Admin&background=0056b3&color=fff" class="rounded-circle me-2" width="32" height="32">
|
||||
<span>Admin</span>
|
||||
</a>
|
||||
|
||||
292
includes/pages/appointments.php
Normal file
292
includes/pages/appointments.php
Normal file
@ -0,0 +1,292 @@
|
||||
<?php
|
||||
// includes/pages/appointments.php
|
||||
?>
|
||||
|
||||
<link href='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/main.min.css' rel='stylesheet' />
|
||||
<script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js'></script>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h3 class="fw-bold text-secondary"><?php echo __('appointments'); ?></h3>
|
||||
<button class="btn btn-primary shadow-sm" onclick="showCreateModal()">
|
||||
<i class="bi bi-calendar-plus me-1"></i> <?php echo __('book_appointment'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filters -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small text-muted"><?php echo __('doctor'); ?> (Filter)</label>
|
||||
<select id="doctorFilter" class="form-select bg-light">
|
||||
<option value=""><?php echo __('all'); ?> <?php echo __('doctors'); ?></option>
|
||||
<?php foreach ($all_doctors as $d): ?>
|
||||
<option value="<?php echo $d['id']; ?>"><?php echo htmlspecialchars($d['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="d-flex align-items-end h-100 pb-1 flex-wrap">
|
||||
<div class="d-flex align-items-center me-3 mb-2">
|
||||
<div class="badge bg-primary me-2" style="width: 15px; height: 15px; border-radius: 50%;"> </div>
|
||||
<small class="text-muted">Scheduled</small>
|
||||
</div>
|
||||
<div class="d-flex align-items-center me-3 mb-2">
|
||||
<div class="badge bg-success me-2" style="width: 15px; height: 15px; border-radius: 50%;"> </div>
|
||||
<small class="text-muted">Completed</small>
|
||||
</div>
|
||||
<div class="d-flex align-items-center me-3 mb-2">
|
||||
<div class="badge bg-danger me-2" style="width: 15px; height: 15px; border-radius: 50%;"> </div>
|
||||
<small class="text-muted">Cancelled</small>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="badge bg-warning me-2" style="width: 15px; height: 15px; border-radius: 50%;"> </div>
|
||||
<small class="text-muted">Holiday</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div id='calendar'></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Appointment Details/Edit Modal -->
|
||||
<div class="modal fade" id="appointmentDetailsModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header border-0 pb-0">
|
||||
<h5 class="modal-title fw-bold text-secondary" id="modalTitle">Appointment Details</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body pt-3">
|
||||
<input type="hidden" id="apt_id">
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted"><?php echo __('patient'); ?></label>
|
||||
<select id="apt_patient_id" class="form-select select2-modal-apt">
|
||||
<?php foreach ($all_patients as $p): ?>
|
||||
<option value="<?php echo $p['id']; ?>"><?php echo htmlspecialchars($p['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted"><?php echo __('doctor'); ?></label>
|
||||
<select id="apt_doctor_id" class="form-select select2-modal-apt">
|
||||
<?php foreach ($all_doctors as $d): ?>
|
||||
<option value="<?php echo $d['id']; ?>"><?php echo htmlspecialchars($d['name']); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label small text-muted"><?php echo __('date'); ?> & <?php echo __('time'); ?></label>
|
||||
<input type="datetime-local" id="apt_start_time" class="form-control">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label small text-muted"><?php echo __('status'); ?></label>
|
||||
<select id="apt_status" class="form-select">
|
||||
<option value="Scheduled">Scheduled</option>
|
||||
<option value="Completed">Completed</option>
|
||||
<option value="Cancelled">Cancelled</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small text-muted"><?php echo __('reason'); ?></label>
|
||||
<textarea id="apt_reason" class="form-control" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer border-0 bg-light rounded-bottom">
|
||||
<div class="d-flex justify-content-between w-100">
|
||||
<button type="button" class="btn btn-outline-danger shadow-sm" id="btnDeleteApt" onclick="deleteAppointment()">
|
||||
<i class="bi bi-trash"></i> <?php echo __('delete'); ?>
|
||||
</button>
|
||||
<div>
|
||||
<button type="button" class="btn btn-secondary shadow-sm me-2" data-bs-dismiss="modal"><?php echo __('cancel'); ?></button>
|
||||
<button type="button" class="btn btn-primary shadow-sm px-4" id="btnSaveApt" onclick="saveAppointment()">
|
||||
<i class="bi bi-check2-circle me-1"></i> <?php echo __('save'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var calendar;
|
||||
|
||||
function initAptSelect2() {
|
||||
if (typeof jQuery !== 'undefined' && jQuery.fn.select2) {
|
||||
$('.select2-modal-apt').each(function() {
|
||||
$(this).select2({
|
||||
dropdownParent: $('#appointmentDetailsModal'),
|
||||
theme: 'bootstrap-5',
|
||||
width: '100%'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showCreateModal(startTime = null) {
|
||||
document.getElementById('modalTitle').innerText = '<?php echo __('book_appointment'); ?>';
|
||||
document.getElementById('apt_id').value = '';
|
||||
document.getElementById('apt_reason').value = '';
|
||||
document.getElementById('apt_status').value = 'Scheduled';
|
||||
document.getElementById('btnDeleteApt').style.display = 'none';
|
||||
|
||||
if (startTime) {
|
||||
var offset = startTime.getTimezoneOffset() * 60000;
|
||||
var localISOTime = (new Date(startTime.getTime() - offset)).toISOString().slice(0, 16);
|
||||
document.getElementById('apt_start_time').value = localISOTime;
|
||||
} else {
|
||||
document.getElementById('apt_start_time').value = new Date().toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
if (document.getElementById('doctorFilter').value) {
|
||||
$('#apt_doctor_id').val(document.getElementById('doctorFilter').value).trigger('change');
|
||||
}
|
||||
|
||||
var modal = new bootstrap.Modal(document.getElementById('appointmentDetailsModal'));
|
||||
modal.show();
|
||||
}
|
||||
|
||||
function saveAppointment() {
|
||||
var id = document.getElementById('apt_id').value;
|
||||
var data = {
|
||||
action: id ? 'update' : 'create',
|
||||
id: id,
|
||||
patient_id: document.getElementById('apt_patient_id').value,
|
||||
doctor_id: document.getElementById('apt_doctor_id').value,
|
||||
start_time: document.getElementById('apt_start_time').value,
|
||||
status: document.getElementById('apt_status').value,
|
||||
reason: document.getElementById('apt_reason').value
|
||||
};
|
||||
|
||||
fetch('api/appointments.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
bootstrap.Modal.getInstance(document.getElementById('appointmentDetailsModal')).hide();
|
||||
calendar.refetchEvents();
|
||||
} else {
|
||||
alert('Error: ' + (result.error || 'Unknown error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteAppointment() {
|
||||
var id = document.getElementById('apt_id').value;
|
||||
if (!id || !confirm('Are you sure you want to delete this appointment?')) return;
|
||||
|
||||
fetch('api/appointments.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ action: 'delete', id: id })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
bootstrap.Modal.getInstance(document.getElementById('appointmentDetailsModal')).hide();
|
||||
calendar.refetchEvents();
|
||||
} else {
|
||||
alert('Error: ' + (result.error || 'Unknown error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
var doctorFilter = document.getElementById('doctorFilter');
|
||||
|
||||
calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'timeGridWeek',
|
||||
headerToolbar: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: 'dayGridMonth,timeGridWeek,timeGridDay'
|
||||
},
|
||||
allDaySlot: true,
|
||||
slotMinTime: '07:00:00',
|
||||
slotMaxTime: '21:00:00',
|
||||
height: 'auto',
|
||||
themeSystem: 'bootstrap5',
|
||||
businessHours: true,
|
||||
events: function(fetchInfo, successCallback, failureCallback) {
|
||||
fetch('api/appointments.php?start=' + fetchInfo.startStr + '&end=' + fetchInfo.endStr + '&doctor_id=' + doctorFilter.value)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.businessHours) {
|
||||
calendar.setOption('businessHours', data.businessHours);
|
||||
}
|
||||
successCallback(data.events);
|
||||
})
|
||||
.catch(error => failureCallback(error));
|
||||
},
|
||||
editable: false,
|
||||
selectable: true,
|
||||
select: function(info) {
|
||||
showCreateModal(info.start);
|
||||
calendar.unselect();
|
||||
},
|
||||
eventClick: function(info) {
|
||||
if (info.event.extendedProps.type === 'appointment') {
|
||||
var props = info.event.extendedProps;
|
||||
document.getElementById('modalTitle').innerText = 'Edit Appointment';
|
||||
document.getElementById('apt_id').value = info.event.id;
|
||||
$('#apt_patient_id').val(props.patient_id).trigger('change');
|
||||
$('#apt_doctor_id').val(props.doctor_id).trigger('change');
|
||||
|
||||
var start = info.event.start;
|
||||
var offset = start.getTimezoneOffset() * 60000;
|
||||
var localISOTime = (new Date(start.getTime() - offset)).toISOString().slice(0, 16);
|
||||
document.getElementById('apt_start_time').value = localISOTime;
|
||||
|
||||
document.getElementById('apt_status').value = props.status;
|
||||
document.getElementById('apt_reason').value = props.reason || '';
|
||||
document.getElementById('btnDeleteApt').style.display = 'block';
|
||||
|
||||
var modal = new bootstrap.Modal(document.getElementById('appointmentDetailsModal'));
|
||||
modal.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
calendar.render();
|
||||
|
||||
doctorFilter.addEventListener('change', function() {
|
||||
calendar.refetchEvents();
|
||||
});
|
||||
|
||||
// Initialize Select2 after some delay to ensure modal is ready
|
||||
$('#appointmentDetailsModal').on('shown.bs.modal', function() {
|
||||
initAptSelect2();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.fc-event { cursor: pointer; border: none; padding: 2px; transition: transform 0.1s ease; }
|
||||
.fc-event:hover { transform: scale(1.02); z-index: 5; }
|
||||
.fc-event-title { font-weight: 500; font-size: 0.85rem; }
|
||||
.fc-col-header-cell { background-color: #f8f9fa; padding: 10px 0 !important; border-bottom: 2px solid #dee2e6 !important; }
|
||||
.fc-day-today { background-color: rgba(0, 45, 98, 0.05) !important; }
|
||||
.fc-toolbar-title { font-weight: 700; color: #002D62; font-size: 1.5rem; }
|
||||
.fc .fc-button-primary { background-color: #002D62; border-color: #002D62; text-transform: capitalize; }
|
||||
.fc .fc-button-primary:hover { background-color: #003a80; border-color: #003a80; }
|
||||
.fc .fc-button-primary:disabled { background-color: #002D62; border-color: #002D62; opacity: 0.65; }
|
||||
.fc-nonbusiness { background-color: rgba(108, 117, 125, 0.1) !important; }
|
||||
.fc-v-event { box-shadow: 0 2px 4px rgba(0,0,0,0.1); border-radius: 4px; }
|
||||
|
||||
.select2-container--bootstrap-5 .select2-selection { border-color: #dee2e6; background-color: #f8f9fa; }
|
||||
.modal-header { border-bottom: none; }
|
||||
.modal-footer { border-top: none; }
|
||||
</style>
|
||||
@ -5,6 +5,8 @@ $today_appointments = $db->query("SELECT COUNT(*) FROM appointments WHERE DATE(a
|
||||
$total_visits = $db->query("SELECT COUNT(*) FROM visits")->fetchColumn();
|
||||
$total_revenue = $db->query("SELECT SUM(total_amount) FROM bills WHERE status = 'Paid'")->fetchColumn() ?: 0;
|
||||
$pending_revenue = $db->query("SELECT SUM(total_amount) FROM bills WHERE status = 'Pending'")->fetchColumn() ?: 0;
|
||||
$total_xrays = $db->query("SELECT COUNT(*) FROM xray_inquiries")->fetchColumn();
|
||||
$total_labs = $db->query("SELECT COUNT(*) FROM laboratory_inquiries")->fetchColumn();
|
||||
|
||||
$patients_sql = "
|
||||
SELECT p.*, ic.name_$lang as insurance_name
|
||||
@ -25,29 +27,46 @@ $appointments = $db->query($appointments_sql)->fetchAll();
|
||||
|
||||
<!-- Dashboard Stats -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card">
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-people"></i>
|
||||
<h3><?php echo $total_patients; ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('total_patients'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card">
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-calendar-check"></i>
|
||||
<h3><?php echo $today_appointments; ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('today_appointments'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card">
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-prescription2 text-info"></i>
|
||||
<h3><?php echo $total_labs; ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('laboratory'); ?> <?php echo __('inquiries'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-x-diamond text-primary"></i>
|
||||
<h3><?php echo $total_xrays; ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('xray'); ?> <?php echo __('inquiries'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-currency-dollar text-success"></i>
|
||||
<h3>$<?php echo number_format($total_revenue, 2); ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('revenue'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card stat-card">
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card stat-card h-100">
|
||||
<i class="bi bi-hourglass-split text-warning"></i>
|
||||
<h3>$<?php echo number_format($pending_revenue, 2); ?></h3>
|
||||
<p class="text-muted mb-0"><?php echo __('pending'); ?></p>
|
||||
@ -60,16 +79,19 @@ $appointments = $db->query($appointments_sql)->fetchAll();
|
||||
<div class="col-12">
|
||||
<div class="card p-3 d-flex flex-row justify-content-between align-items-center">
|
||||
<h5 class="mb-0 fw-bold"><?php echo __('dashboard'); ?></h5>
|
||||
<div>
|
||||
<button class="btn btn-primary btn-sm me-2" data-bs-toggle="modal" data-bs-target="#addPatientModal">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addPatientModal">
|
||||
<i class="bi bi-plus-lg"></i> <?php echo __('add_patient'); ?>
|
||||
</button>
|
||||
<button class="btn btn-success btn-sm me-2" data-bs-toggle="modal" data-bs-target="#bookAppointmentModal">
|
||||
<button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#bookAppointmentModal">
|
||||
<i class="bi bi-calendar-plus"></i> <?php echo __('book_appointment'); ?>
|
||||
</button>
|
||||
<button class="btn btn-info btn-sm text-white" data-bs-toggle="modal" data-bs-target="#recordVisitModal">
|
||||
<i class="bi bi-clipboard-plus"></i> <?php echo __('add_visit'); ?>
|
||||
</button>
|
||||
<button class="btn btn-warning btn-sm text-white" data-bs-toggle="modal" data-bs-target="#addXrayInquiryModal">
|
||||
<i class="bi bi-x-diamond"></i> <?php echo __('add_xray_inquiry'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -77,10 +99,10 @@ $appointments = $db->query($appointments_sql)->fetchAll();
|
||||
|
||||
<!-- Tables Section -->
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-header py-3">
|
||||
<h6 class="mb-0 fw-bold"><i class="bi bi-people-fill me-2 text-primary"></i> <?php echo __('patients'); ?></h6>
|
||||
<h6 class="mb-0 fw-bold text-white"><i class="bi bi-people-fill me-2"></i> <?php echo __('patients'); ?></h6>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
@ -110,10 +132,10 @@ $appointments = $db->query($appointments_sql)->fetchAll();
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card shadow-sm h-100">
|
||||
<div class="card-header py-3">
|
||||
<h6 class="mb-0 fw-bold"><i class="bi bi-calendar-event-fill me-2 text-primary"></i> <?php echo __('appointments'); ?></h6>
|
||||
<h6 class="mb-0 fw-bold text-white"><i class="bi bi-calendar-event-fill me-2"></i> <?php echo __('appointments'); ?></h6>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
|
||||
@ -22,7 +22,7 @@ $inquiries = $stmt->fetchAll();
|
||||
// Fetch tests for each inquiry
|
||||
foreach ($inquiries as &$inquiry) {
|
||||
$stmt = $db->prepare("
|
||||
SELECT it.*, t.name_$lang as test_name
|
||||
SELECT it.*, t.name_$lang as test_name, t.normal_range as reference_range
|
||||
FROM inquiry_tests it
|
||||
JOIN laboratory_tests t ON it.test_id = t.id
|
||||
WHERE it.inquiry_id = ?");
|
||||
@ -103,7 +103,9 @@ unset($inquiry);
|
||||
</td>
|
||||
<td>
|
||||
<?php foreach ($inquiry['tests'] as $test): ?>
|
||||
<span class="badge bg-light text-dark border me-1 small mb-1"><?php echo htmlspecialchars($test['test_name']); ?></span>
|
||||
<span class="badge bg-light text-dark border me-1 small mb-1" data-bs-toggle="tooltip" title="Ref: <?php echo htmlspecialchars($test['reference_range']); ?>">
|
||||
<?php echo htmlspecialchars($test['test_name']); ?>: <strong><?php echo htmlspecialchars($test['result'] ?: '-'); ?></strong>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<td class="text-end px-4">
|
||||
@ -134,6 +136,3 @@ unset($inquiry);
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
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); ?>;
|
||||
</script>
|
||||
|
||||
61
includes/pages/xray_groups.php
Normal file
61
includes/pages/xray_groups.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
$query = "SELECT * FROM xray_groups ORDER BY id DESC";
|
||||
$stmt = $db->query($query);
|
||||
$groups = $stmt->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h3 class="fw-bold text-secondary"><?php echo __('xray_groups'); ?></h3>
|
||||
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addXrayGroupModal">
|
||||
<i class="bi bi-plus-lg me-1"></i> <?php echo __('add_xray_group'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light text-secondary">
|
||||
<tr>
|
||||
<th class="px-4 py-3">#</th>
|
||||
<th class="py-3"><?php echo __('name_en'); ?></th>
|
||||
<th class="py-3"><?php echo __('name_ar'); ?></th>
|
||||
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($groups)): ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-collection display-4 d-block mb-3"></i>
|
||||
No groups found.
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($groups as $group): ?>
|
||||
<tr>
|
||||
<td class="px-4 text-secondary"><?php echo $group['id']; ?></td>
|
||||
<td class="fw-semibold text-dark"><?php echo htmlspecialchars($group['name_en']); ?></td>
|
||||
<td class="text-secondary"><?php echo htmlspecialchars($group['name_ar']); ?></td>
|
||||
<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)); ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
<button class="btn btn-link text-danger py-1 px-2"
|
||||
onclick="showDeleteXrayGroupModal(<?php echo $group['id']; ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
143
includes/pages/xray_inquiries.php
Normal file
143
includes/pages/xray_inquiries.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
?>
|
||||
|
||||
<?php
|
||||
$search_patient = $_GET['patient'] ?? '';
|
||||
$search_status = $_GET['status'] ?? '';
|
||||
|
||||
$query = "SELECT * FROM xray_inquiries WHERE 1=1";
|
||||
$params = [];
|
||||
|
||||
if ($search_patient) {
|
||||
$query .= " AND patient_name LIKE ?";
|
||||
$params[] = "%$search_patient%";
|
||||
}
|
||||
if ($search_status) {
|
||||
$query .= " AND status = ?";
|
||||
$params[] = $search_status;
|
||||
}
|
||||
|
||||
$query .= " ORDER BY inquiry_date DESC";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$inquiries = $stmt->fetchAll();
|
||||
|
||||
// Fetch items for each inquiry
|
||||
foreach ($inquiries as &$inquiry) {
|
||||
$stmt = $db->prepare("
|
||||
SELECT it.*, t.name_$lang as xray_name
|
||||
FROM xray_inquiry_items it
|
||||
JOIN xray_tests t ON it.xray_id = t.id
|
||||
WHERE it.inquiry_id = ?");
|
||||
$stmt->execute([$inquiry['id']]);
|
||||
$inquiry['items'] = $stmt->fetchAll();
|
||||
}
|
||||
unset($inquiry);
|
||||
|
||||
$all_xrays_list = $db->query("SELECT id, name_$lang as name FROM xray_tests ORDER BY name_$lang ASC")->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h3 class="fw-bold text-secondary"><?php echo __('xray_inquiries'); ?></h3>
|
||||
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addXrayInquiryModal">
|
||||
<i class="bi bi-plus-circle me-1"></i> <?php echo __('add_xray_inquiry'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<form method="GET" action="" class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0 text-muted"><i class="bi bi-search"></i></span>
|
||||
<input type="text" name="patient" class="form-control bg-light border-start-0" placeholder="<?php echo __('patient'); ?>" value="<?php echo htmlspecialchars($search_patient); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<select name="status" class="form-select bg-light">
|
||||
<option value=""><?php echo __('status'); ?> (<?php echo __('all'); ?>)</option>
|
||||
<option value="Pending" <?php echo $search_status == 'Pending' ? 'selected' : ''; ?>><?php echo __('Pending'); ?></option>
|
||||
<option value="Completed" <?php echo $search_status == 'Completed' ? 'selected' : ''; ?>><?php echo __('Completed'); ?></option>
|
||||
<option value="Cancelled" <?php echo $search_status == 'Cancelled' ? 'selected' : ''; ?>><?php echo __('Cancelled'); ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-secondary w-100"><?php echo __('search'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light text-secondary">
|
||||
<tr>
|
||||
<th class="px-4 py-3">#</th>
|
||||
<th class="py-3"><?php echo __('patient'); ?></th>
|
||||
<th class="py-3"><?php echo __('inquiry_date'); ?></th>
|
||||
<th class="py-3"><?php echo __('status'); ?></th>
|
||||
<th class="py-3"><?php echo __('xrays'); ?></th>
|
||||
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($inquiries)): ?>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-question-circle display-4 d-block mb-3"></i>
|
||||
No inquiries found.
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($inquiries as $inquiry): ?>
|
||||
<tr>
|
||||
<td class="px-4 text-secondary"><?php echo $inquiry['id']; ?></td>
|
||||
<td class="fw-semibold text-dark"><?php echo htmlspecialchars($inquiry['patient_name']); ?></td>
|
||||
<td class="text-secondary small"><?php echo $inquiry['inquiry_date']; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
$status_class = 'bg-secondary';
|
||||
if ($inquiry['status'] == 'Completed') $status_class = 'bg-success';
|
||||
if ($inquiry['status'] == 'Pending') $status_class = 'bg-warning';
|
||||
if ($inquiry['status'] == 'Cancelled') $status_class = 'bg-danger';
|
||||
?>
|
||||
<span class="badge <?php echo $status_class; ?>"><?php echo __($inquiry['status']); ?></span>
|
||||
</td>
|
||||
<td>
|
||||
<?php foreach ($inquiry['items'] as $item): ?>
|
||||
<span class="badge bg-light text-dark border me-1 mb-1">
|
||||
<?php echo htmlspecialchars($item['xray_name']); ?>
|
||||
<?php if ($item['result']): ?>: <span class="text-primary"><?php echo htmlspecialchars($item['result']); ?></span><?php endif; ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
</td>
|
||||
<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)); ?>)"
|
||||
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)); ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
<button class="btn btn-link text-danger py-1 px-2"
|
||||
onclick="showDeleteXrayInquiryModal(<?php echo $inquiry['id']; ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
128
includes/pages/xray_tests.php
Normal file
128
includes/pages/xray_tests.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
$search_name = $_GET['name'] ?? '';
|
||||
$search_group = $_GET['group_id'] ?? '';
|
||||
|
||||
$query = "
|
||||
SELECT t.*, g.name_$lang as group_name
|
||||
FROM xray_tests t
|
||||
LEFT JOIN xray_groups g ON t.group_id = g.id
|
||||
WHERE 1=1";
|
||||
$params = [];
|
||||
|
||||
if ($search_name) {
|
||||
$query .= " AND (t.name_en LIKE ? OR t.name_ar LIKE ?)";
|
||||
$params[] = "%$search_name%";
|
||||
$params[] = "%$search_name%";
|
||||
}
|
||||
if ($search_group) {
|
||||
$query .= " AND t.group_id = ?";
|
||||
$params[] = $search_group;
|
||||
}
|
||||
|
||||
$query .= " ORDER BY t.id DESC";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->execute($params);
|
||||
$tests = $stmt->fetchAll();
|
||||
|
||||
// Fetch all xray groups for the dropdown
|
||||
$all_xray_groups_list = $db->query("SELECT id, name_$lang as name FROM xray_groups ORDER BY name_$lang ASC")->fetchAll();
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h3 class="fw-bold text-secondary"><?php echo __('xray_tests'); ?></h3>
|
||||
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addXrayTestModal">
|
||||
<i class="bi bi-plus-circle me-1"></i> <?php echo __('add_xray_test'); ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<form method="GET" action="" class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text bg-light border-end-0 text-muted"><i class="bi bi-search"></i></span>
|
||||
<input type="text" name="name" class="form-control bg-light border-start-0" placeholder="<?php echo __('xray_name'); ?>" value="<?php echo htmlspecialchars($search_name); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<select name="group_id" class="form-select bg-light">
|
||||
<option value=""><?php echo __('xray_group'); ?> (<?php echo __('all'); ?>)</option>
|
||||
<?php foreach ($all_xray_groups_list as $group): ?>
|
||||
<option value="<?php echo $group['id']; ?>" <?php echo $search_group == $group['id'] ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($group['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-secondary w-100"><?php echo __('search'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light text-secondary">
|
||||
<tr>
|
||||
<th class="px-4 py-3">#</th>
|
||||
<th class="py-3"><?php echo __('xray_name'); ?></th>
|
||||
<th class="py-3"><?php echo __('xray_group'); ?></th>
|
||||
<th class="py-3"><?php echo __('price'); ?></th>
|
||||
<th class="py-3 text-end px-4"><?php echo __('actions'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($tests)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="text-center py-5 text-muted">
|
||||
<i class="bi bi-prescription2 display-4 d-block mb-3"></i>
|
||||
<?php echo __('no_xrays_found'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($tests as $test): ?>
|
||||
<tr>
|
||||
<td class="px-4 fw-medium text-secondary"><?php echo $test['id']; ?></td>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="bg-primary bg-opacity-10 text-primary p-2 rounded-circle me-3">
|
||||
<i class="bi bi-list-check fs-5"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-semibold text-dark"><?php echo htmlspecialchars($test['name_'.$lang]); ?></div>
|
||||
<small class="text-muted"><?php echo htmlspecialchars($test['name_'.($lang == 'en' ? 'ar' : 'en')]); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-info bg-opacity-10 text-info border border-info border-opacity-25 px-2 py-1">
|
||||
<?php echo htmlspecialchars($test['group_name'] ?? '-'); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-secondary fw-bold"><?php echo number_format($test['price'], 2); ?></td>
|
||||
<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)); ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('edit'); ?>">
|
||||
<i class="bi bi-pencil-square"></i>
|
||||
</button>
|
||||
<button class="btn btn-link text-danger py-1 px-2"
|
||||
onclick="showDeleteXrayTestModal(<?php echo $test['id']; ?>)"
|
||||
data-bs-toggle="tooltip" title="<?php echo __('delete'); ?>">
|
||||
<i class="bi bi-trash3"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
36
lang.php
36
lang.php
@ -170,7 +170,22 @@ $translations = [
|
||||
'notes' => 'Notes',
|
||||
'result' => 'Result',
|
||||
'print' => 'Print',
|
||||
'add_test' => 'Add Test'
|
||||
'xray' => 'X-Ray',
|
||||
'xray_tests' => 'X-Ray Tests',
|
||||
'xray_groups' => 'X-Ray Groups',
|
||||
'xray_inquiries' => 'X-Ray Inquiries',
|
||||
'add_xray_group' => 'Add X-Ray Group',
|
||||
'edit_xray_group' => 'Edit X-Ray Group',
|
||||
'add_xray_test' => 'Add X-Ray Test',
|
||||
'edit_xray_test' => 'Edit X-Ray Test',
|
||||
'add_xray_inquiry' => 'Add X-Ray Inquiry',
|
||||
'edit_xray_inquiry' => 'Edit X-Ray Inquiry',
|
||||
'no_xrays_found' => 'No X-Rays found',
|
||||
'xray_name' => 'X-Ray Name',
|
||||
'xray_group' => 'X-Ray Group',
|
||||
'groups' => 'Groups',
|
||||
'add_xray' => 'Add X-Ray',
|
||||
'xrays' => 'X-Rays'
|
||||
],
|
||||
'ar' => [
|
||||
'dashboard' => 'لوحة القيادة',
|
||||
@ -292,7 +307,7 @@ $translations = [
|
||||
'edit_nurse' => 'تعديل ممرضة',
|
||||
'update_nurse' => 'تحديث بيانات الممرضة',
|
||||
'delete_nurse' => 'حذف ممرضة',
|
||||
'no_nurses_found' => 'لم يتم العثور على ممرضات',
|
||||
'no_nurses_found' => 'لم يتم العور على ممرضات',
|
||||
'settings' => 'الإعدادات',
|
||||
'employees' => 'الموظفون',
|
||||
'poisons' => 'السموم',
|
||||
@ -342,6 +357,21 @@ $translations = [
|
||||
'notes' => 'ملاحظات',
|
||||
'result' => 'النتيجة',
|
||||
'print' => 'طباعة',
|
||||
'add_test' => 'إضافة فحص'
|
||||
'xray' => 'الأشعة',
|
||||
'xray_tests' => 'فحوصات الأشعة',
|
||||
'xray_groups' => 'مجموعات الأشعة',
|
||||
'xray_inquiries' => 'استفسارات الأشعة',
|
||||
'add_xray_group' => 'إضافة مجموعة أشعة',
|
||||
'edit_xray_group' => 'تعديل مجموعة أشعة',
|
||||
'add_xray_test' => 'إضافة فحص أشعة',
|
||||
'edit_xray_test' => 'تعديل فحص أشعة',
|
||||
'add_xray_inquiry' => 'إضافة استفسار أشعة',
|
||||
'edit_xray_inquiry' => 'تعديل استفسار أشعة',
|
||||
'no_xrays_found' => 'لم يتم العثور على فحوصات أشعة',
|
||||
'xray_name' => 'اسم فحص الأشعة',
|
||||
'xray_group' => 'مجموعة الأشعة',
|
||||
'groups' => 'المجموعات',
|
||||
'add_xray' => 'إضافة أشعة',
|
||||
'xrays' => 'الأشعة'
|
||||
]
|
||||
];
|
||||
14
xray_groups.php
Normal file
14
xray_groups.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
$section = 'xray_groups';
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$db = db();
|
||||
$lang = $_SESSION['lang'];
|
||||
|
||||
require_once __DIR__ . '/includes/actions.php';
|
||||
require_once __DIR__ . '/includes/common_data.php';
|
||||
require_once __DIR__ . '/includes/layout/header.php';
|
||||
require_once __DIR__ . '/includes/pages/xray_groups.php';
|
||||
require_once __DIR__ . '/includes/layout/footer.php';
|
||||
?>
|
||||
14
xray_inquiries.php
Normal file
14
xray_inquiries.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
$section = 'xray_inquiries';
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$db = db();
|
||||
$lang = $_SESSION['lang'];
|
||||
|
||||
require_once __DIR__ . '/includes/actions.php';
|
||||
require_once __DIR__ . '/includes/common_data.php';
|
||||
require_once __DIR__ . '/includes/layout/header.php';
|
||||
require_once __DIR__ . '/includes/pages/xray_inquiries.php';
|
||||
require_once __DIR__ . '/includes/layout/footer.php';
|
||||
?>
|
||||
14
xray_tests.php
Normal file
14
xray_tests.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
$section = 'xray_tests';
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/helpers.php';
|
||||
|
||||
$db = db();
|
||||
$lang = $_SESSION['lang'];
|
||||
|
||||
require_once __DIR__ . '/includes/actions.php';
|
||||
require_once __DIR__ . '/includes/common_data.php';
|
||||
require_once __DIR__ . '/includes/layout/header.php';
|
||||
require_once __DIR__ . '/includes/pages/xray_tests.php';
|
||||
require_once __DIR__ . '/includes/layout/footer.php';
|
||||
?>
|
||||
Loading…
x
Reference in New Issue
Block a user