From ae36a7f86c6285d926db04a8ef9f922be2518fb3 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 16 Nov 2025 17:25:40 +0000 Subject: [PATCH] Auto commit: 2025-11-16T17:25:40.198Z --- api/patients.php | 63 ++++++++++ assets/css/custom.css | 66 +++++++++++ assets/js/main.js | 98 ++++++++++++++++ db/config.php | 53 ++++++--- db/db_setup.php | 22 ++++ index.php | 259 +++++++++++++++++++----------------------- 6 files changed, 403 insertions(+), 158 deletions(-) create mode 100644 api/patients.php create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 db/db_setup.php diff --git a/api/patients.php b/api/patients.php new file mode 100644 index 0000000..30ab377 --- /dev/null +++ b/api/patients.php @@ -0,0 +1,63 @@ + 'error', 'message' => 'Invalid request']; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $input = json_decode(file_get_contents('php://input'), true); + + if (json_last_error() !== JSON_ERROR_NONE) { + $response['message'] = 'Invalid JSON received.'; + echo json_encode($response); + exit; + } + + // Basic validation + if (empty($input['first_name']) || empty($input['last_name']) || empty($input['date_of_birth']) || empty($input['gender']) || empty($input['contact_number'])) { + $response['message'] = 'All fields are required.'; + } else { + try { + $pdo = db(); + $stmt = $pdo->prepare("INSERT INTO patients (first_name, last_name, date_of_birth, gender, contact_number) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([ + htmlspecialchars($input['first_name']), + htmlspecialchars($input['last_name']), + $input['date_of_birth'], + htmlspecialchars($input['gender']), + htmlspecialchars($input['contact_number']) + ]); + + $patientId = $pdo->lastInsertId(); + + $response = [ + 'status' => 'success', + 'message' => 'Patient registered successfully.', + 'patient' => [ + 'id' => $patientId, + 'first_name' => htmlspecialchars($input['first_name']), + 'last_name' => htmlspecialchars($input['last_name']), + 'date_of_birth' => $input['date_of_birth'], + 'gender' => htmlspecialchars($input['gender']), + 'contact_number' => htmlspecialchars($input['contact_number']), + 'created_at' => date('Y-m-d H:i:s') + ] + ]; + } catch (PDOException $e) { + // In a real app, log this error. Don't expose it to the user. + $response['message'] = 'Database error: ' . $e->getMessage(); + } + } +} elseif ($_SERVER['REQUEST_METHOD'] === 'GET') { + try { + $pdo = db(); + $stmt = $pdo->query("SELECT id, first_name, last_name, date_of_birth, gender, contact_number, DATE_FORMAT(created_at, '%Y-%m-%d') as registration_date FROM patients ORDER BY created_at DESC LIMIT 20"); + $patients = $stmt->fetchAll(); + $response = ['status' => 'success', 'patients' => $patients]; + } catch (PDOException $e) { + $response['message'] = 'Database error: ' . $e->getMessage(); + } +} + +echo json_encode($response); diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..41be7c3 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,66 @@ +/* General Body Styles */ +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background-color: #f8f9fa; + color: #212529; +} + +/* Main container */ +.container { + max-width: 1200px; +} + +/* Header */ +.header-title { + font-weight: 700; + color: #343a40; +} + +/* Main card for content */ +.card { + border: none; + border-radius: 0.5rem; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); +} + +/* Table styles */ +.table { + margin-bottom: 0; +} + +.table thead th { + border-bottom-width: 1px; + font-weight: 600; + text-transform: uppercase; + font-size: 0.8rem; + letter-spacing: 0.5px; + color: #495057; +} + +.table tbody tr:hover { + background-color: #f1f3f5; +} + +/* Modal styles */ +.modal-header { + border-bottom: none; +} + +.modal-content { + border-radius: 0.5rem; +} + +/* Toast notifications */ +.toast { + border-radius: 0.375rem; +} + +/* Button styles */ +.btn-primary { + transition: all 0.2s ease-in-out; +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..ffc061a --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,98 @@ +document.addEventListener('DOMContentLoaded', function () { + const registrationForm = document.getElementById('registrationForm'); + const patientTableBody = document.getElementById('patientTableBody'); + const toastContainer = document.getElementById('toastContainer'); + + // --- Function to show a toast notification --- + function showToast(message, type = 'success') { + const toastId = 'toast-' + Date.now(); + const toastHTML = ` + + `; + toastContainer.innerHTML += toastHTML; + const toastElement = document.getElementById(toastId); + const toast = new bootstrap.Toast(toastElement, { delay: 5000 }); + toast.show(); + toastElement.addEventListener('hidden.bs.toast', () => toastElement.remove()); + } + + // --- Function to add a patient to the table --- + function addPatientToTable(patient) { + const row = document.createElement('tr'); + row.innerHTML = ` + ${patient.id} + ${patient.first_name} ${patient.last_name} + ${patient.date_of_birth} + ${patient.gender} + ${patient.contact_number} + ${patient.registration_date || new Date().toISOString().split('T')[0]} + `; + patientTableBody.prepend(row); + } + + // --- Fetch and display initial patients --- + async function loadInitialPatients() { + try { + const response = await fetch('api/patients.php'); + if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); + const data = await response.json(); + + if (data.status === 'success' && data.patients) { + patientTableBody.innerHTML = ''; // Clear existing rows + data.patients.forEach(addPatientToTable); + } else { + showToast(data.message || 'Could not load patients.', 'danger'); + } + } catch (error) { + console.error('Fetch error:', error); + showToast('An error occurred while fetching patient data.', 'danger'); + } + } + + // --- Handle form submission --- + if (registrationForm) { + registrationForm.addEventListener('submit', async function (e) { + e.preventDefault(); + + const formData = new FormData(registrationForm); + const patientData = Object.fromEntries(formData.entries()); + + try { + const response = await fetch('api/patients.php', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(patientData) + }); + + if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); + + const result = await response.json(); + + if (result.status === 'success') { + showToast('Patient registered successfully!'); + addPatientToTable(result.patient); + registrationForm.reset(); + const modal = bootstrap.Modal.getInstance(document.getElementById('registerPatientModal')); + modal.hide(); + } else { + showToast(result.message || 'Registration failed.', 'danger'); + } + } catch (error) { + console.error('Submit error:', error); + showToast('An error occurred during registration.', 'danger'); + } + }); + } + + // --- Initial load --- + loadInitialPatients(); +}); diff --git a/db/config.php b/db/config.php index d24ecd8..e9ea3c4 100644 --- a/db/config.php +++ b/db/config.php @@ -1,17 +1,42 @@ PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - ]); - } - return $pdo; +// Database configuration +define('DB_HOST', getenv('DB_HOST') ?: '127.0.0.1'); +define('DB_PORT', getenv('DB_PORT') ?: '3306'); +define('DB_NAME', getenv('DB_NAME') ?: 'main'); +define('DB_USER', getenv('DB_USER') ?: 'admin'); +define('DB_PASS', getenv('DB_PASS') ?: 'admin'); + +if (!function_exists('db')) { + /** + * Establishes a PDO database connection. + * + * @return PDO The PDO database connection object. + * @throws PDOException If the connection fails. + */ + function db(): PDO + { + static $pdo = null; + + if ($pdo === null) { + $dsn = 'mysql:host=' . DB_HOST . ';port=' . DB_PORT . ';dbname=' . DB_NAME . ';charset=utf8mb4'; + $options = [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + try { + $pdo = new PDO($dsn, DB_USER, DB_PASS, $options); + } catch (PDOException $e) { + // In a real app, you would log this error and show a generic error page. + // For development, it's okay to show the error. + throw new PDOException($e->getMessage(), (int)$e->getCode()); + } + } + + return $pdo; + } } + + diff --git a/db/db_setup.php b/db/db_setup.php new file mode 100644 index 0000000..d5ca9ec --- /dev/null +++ b/db/db_setup.php @@ -0,0 +1,22 @@ +exec($sql); + // You can add a success message here if running from CLI + // echo "Table 'patients' created successfully (if it didn't exist)."; +} catch (PDOException $e) { + // In a real app, you'd log this error, not display it + die("DB ERROR: " . $e->getMessage()); +} diff --git a/index.php b/index.php index 7205f3d..9b0897d 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,121 @@ - - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + HIMS - Hospital Information Management System + + + + + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+

Hospital Information Management System

+ +
+ +
+
+
Recently Registered Patients
+
+
+
+ + + + + + + + + + + + + + + +
IDNameDate of BirthGenderContactRegistration Date
Loading patient data...
+
+
+
+
+ + + -
- + + +
+ + + + + - + \ No newline at end of file