287 lines
9.0 KiB
PHP

<?php
namespace App\Controllers;
use App\Models\UserModel;
use App\Models\DoctorModel;
use App\Models\PatientModel;
use App\Models\AppointmentModel;
class Admin extends BaseController
{
public function dashboard()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$doctorModel = new DoctorModel();
$patientModel = new PatientModel();
$appointmentModel = new AppointmentModel();
$data['totalDoctors'] = $doctorModel->countAll();
$data['totalPatients'] = $patientModel->countAll();
$data['totalAppointments'] = $appointmentModel->countAll();
return view('admin/dashboard', $data);
}
public function overview()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$data=[];
return view('admin/overview', $data);
}
public function doctors()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$db = \Config\Database::connect();
$query = $db->query("
SELECT users.id, users.name, users.email, doctors.specialization
FROM users
JOIN doctors ON doctors.user_id = users.id
WHERE users.role = 'doctor'
");
$data['doctors'] = $query->getResult();
return view('admin/doctors', $data);
}
public function deleteDoctor($id)
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$id = (int) $id;
if ($id < 1) {
return redirect()->to(site_url('admin/doctors'));
}
$userModel = new UserModel();
$doctorModel = new DoctorModel();
$db = \Config\Database::connect();
$doctor = $doctorModel->where('user_id', $id)->first();
if ($doctor) {
$db->table('appointments')->where('doctor_id', $doctor['id'])->delete();
$doctorModel->delete($doctor['id']);
}
$userModel->delete($id);
return redirect()->to(site_url('admin/doctors'));
}
public function patients()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$db = \Config\Database::connect();
$query = $db->query("
SELECT users.id, users.name, users.email, patients.phone
FROM users
JOIN patients ON patients.user_id = users.id
WHERE users.role = 'patient'
");
$data['patients'] = $query->getResult();
return view('admin/patients', $data);
}
public function deletePatient($id)
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$id = (int) $id;
if ($id < 1) {
return redirect()->to(site_url('admin/patients'));
}
$userModel = new UserModel();
$patientModel = new PatientModel();
$db = \Config\Database::connect();
$patient = $patientModel->where('user_id', $id)->first();
if ($patient) {
$db->table('appointments')->where('patient_id', $patient['id'])->delete();
$patientModel->delete($patient['id']);
}
$userModel->delete($id);
return redirect()->to(site_url('admin/patients'));
}
public function appointments()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$db = \Config\Database::connect();
$query = $db->query("
SELECT a.*, u1.name as patient_name, u2.name as doctor_name
FROM appointments a
JOIN patients p ON p.id = a.patient_id
JOIN users u1 ON u1.id = p.user_id
JOIN doctors d ON d.id = a.doctor_id
JOIN users u2 ON u2.id = d.user_id
");
$data['appointments'] = $query->getResult();
return view('admin/appointments', $data);
}
public function addDoctor()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
return view('admin/add_doctor');
}
public function storeDoctor()
{
if ($r = $this->requireRole('admin')) {
return $r;
}
$userModel = new UserModel();
$doctorModel = new DoctorModel();
$db = \Config\Database::connect();
$validation = \Config\Services::validation();
$entries = $this->request->getPost('doctors');
if (! is_array($entries) || $entries === []) {
$entries = [[
'name' => $this->request->getPost('name'),
'email' => $this->request->getPost('email'),
'password' => $this->request->getPost('password'),
'specialization' => $this->request->getPost('specialization'),
'experience' => $this->request->getPost('experience'),
'fees' => $this->request->getPost('fees'),
'available_from' => $this->request->getPost('available_from'),
'available_to' => $this->request->getPost('available_to'),
]];
}
$rules = [
'name' => 'required|min_length[3]|max_length[100]',
'email' => 'required|valid_email',
'password' => 'required|min_length[8]',
'specialization' => 'required|min_length[2]|max_length[191]',
'experience' => 'permit_empty|max_length[100]',
'fees' => 'permit_empty|decimal',
'available_from' => 'permit_empty|valid_date[H:i]',
'available_to' => 'permit_empty|valid_date[H:i]',
];
$emailsSeen = [];
$cleanRows = [];
$error = null;
foreach ($entries as $i => $row) {
$row = [
'name' => trim((string) ($row['name'] ?? '')),
'email' => trim((string) ($row['email'] ?? '')),
'password' => (string) ($row['password'] ?? ''),
'specialization' => trim((string) ($row['specialization'] ?? '')),
'experience' => trim((string) ($row['experience'] ?? '')),
'fees' => trim((string) ($row['fees'] ?? '')),
'available_from' => trim((string) ($row['available_from'] ?? '')),
'available_to' => trim((string) ($row['available_to'] ?? '')),
];
$rowNumber = $i + 1;
if (! $validation->setRules($rules)->run($row)) {
$rowErrors = $validation->getErrors();
$error = 'Row ' . $rowNumber . ': ' . implode(', ', array_values($rowErrors));
break;
}
$emailKey = strtolower($row['email']);
if (isset($emailsSeen[$emailKey])) {
$error = 'Row ' . $rowNumber . ': Duplicate email in submitted rows.';
break;
}
$emailsSeen[$emailKey] = true;
if ($userModel->where('email', $row['email'])->first()) {
$error = 'Row ' . $rowNumber . ': Email already exists.';
break;
}
$cleanRows[] = $row;
}
if ($error !== null || $cleanRows === []) {
return redirect()->back()->withInput()->with('error', $error ?? 'Please provide at least one doctor row.');
}
$db->transStart();
foreach ($cleanRows as $row) {
$userData = [
'name' => $row['name'],
'email' => $row['email'],
'password' => password_hash($row['password'], PASSWORD_DEFAULT),
'role' => 'doctor',
'status' => 'active',
];
if (! $userModel->skipValidation(true)->insert($userData)) {
$db->transRollback();
return redirect()->back()->withInput()->with('error', 'Could not create user for ' . $row['email'] . '.');
}
$userId = (int) $userModel->getInsertID();
$doctorRow = [
'user_id' => $userId,
'specialization' => $row['specialization'],
'experience' => $row['experience'] !== '' ? $row['experience'] : null,
'fees' => $row['fees'] !== '' ? $row['fees'] : null,
'available_from' => $row['available_from'] !== '' ? $row['available_from'] : null,
'available_to' => $row['available_to'] !== '' ? $row['available_to'] : null,
];
if (! $doctorModel->skipValidation(true)->insert($doctorRow)) {
$db->transRollback();
return redirect()->back()->withInput()->with('error', 'Could not create doctor profile for ' . $row['email'] . '.');
}
}
$db->transComplete();
if (! $db->transStatus()) {
return redirect()->back()->withInput()->with('error', 'Transaction failed.');
}
$created = count($cleanRows);
return redirect()->to(site_url('admin/doctors'))->with('success', $created . ' doctor account(s) created.');
}
}