table('doctor_specializations ds') ->select('s.name') ->join('specializations s', 's.id = ds.specialization_id') ->where('ds.doctor_id', $doctorId) ->orderBy('s.name', 'ASC') ->get() ->getResultArray(); return array_map(static fn ($row) => $row['name'], $rows); } public function dashboard() { if ($r = $this->requireRole('doctor')) { return $r; } $db = \Config\Database::connect(); $userId = (int) session()->get('id'); $doctorModel = new DoctorModel(); $doctor = $doctorModel->where('user_id', $userId)->first(); if (! $doctor) { return redirect()->to(site_url('/'))->with('error', 'Doctor profile not found.'); } $doctorId = (int) $doctor['id']; $query = $db->query(' SELECT a.*, TRIM(CONCAT(COALESCE(u.first_name, \'\'), \' \', COALESCE(u.last_name, \'\'))) AS patient_name FROM appointments a JOIN patients p ON p.id = a.patient_id JOIN users u ON u.id = p.user_id WHERE a.doctor_id = ? ', [$doctorId]); $data['appointments'] = $query->getResult(); return view('doctor/dashboard', $data); } public function profile() { if ($r = $this->requireRole('doctor')) { return $r; } $doctorModel = new DoctorModel(); $specializationModel = new SpecializationModel(); $userId = (int) session()->get('id'); $doctor = $doctorModel->where('user_id', $userId)->first(); if (! $doctor) { return redirect()->to(site_url('/'))->with('error', 'Doctor profile not found.'); } if ($this->request->is('post')) { $rules = [ 'specialization' => 'required', 'experience' => 'required|max_length[100]', 'fees' => 'permit_empty|decimal', ]; if (! $this->validate($rules)) { return redirect()->back()->withInput(); } $specializations = $this->parseSpecializations($this->request->getPost('specialization')); if ($specializations === []) { return redirect()->back()->withInput()->with('error', 'Please select at least one specialization.'); } $update = [ 'specialization' => implode(', ', $specializations), 'experience' => $this->request->getPost('experience') ?: null, 'fees' => $this->request->getPost('fees') !== '' && $this->request->getPost('fees') !== null ? $this->request->getPost('fees') : null, ]; if (! $doctorModel->update($doctor['id'], $update)) { return redirect()->back()->withInput()->with('error', 'Could not update profile.'); } $specializationMap = $specializationModel->ensureNamesExist($specializations); $doctorSpecializationModel = new DoctorSpecializationModel(); $doctorSpecializationModel->syncDoctorSpecializations($doctor['id'], array_values($specializationMap), (int) session()->get('id')); return redirect()->to(site_url('doctor/profile'))->with('success', 'Profile updated.'); } $selectedSpecializations = $this->getDoctorSpecializationNames((int) $doctor['id']); if ($selectedSpecializations === [] && ! empty($doctor['specialization'])) { $selectedSpecializations = $this->parseSpecializations($doctor['specialization']); } return view('doctor/profile', [ 'doctor' => $doctor, 'specializationOptions' => $specializationModel->getOptionNames(), 'selectedSpecializations' => $selectedSpecializations, ]); } public function accept($id): ResponseInterface { if ($r = $this->requireRole('doctor')) { return $r; } if (! $this->request->is('post')) { return redirect()->to(site_url('doctor/dashboard'))->with('error', 'Invalid request.'); } return $this->updateAppointmentStatus((int) $id, 'approved'); } public function reject($id): ResponseInterface { if ($r = $this->requireRole('doctor')) { return $r; } if (! $this->request->is('post')) { return redirect()->to(site_url('doctor/dashboard'))->with('error', 'Invalid request.'); } return $this->updateAppointmentStatus((int) $id, 'rejected'); } private function updateAppointmentStatus(int $appointmentId, string $status): RedirectResponse { if ($appointmentId < 1) { return redirect()->back(); } $appointmentModel = new AppointmentModel(); $doctorModel = new DoctorModel(); $userId = (int) session()->get('id'); $doctor = $doctorModel->where('user_id', $userId)->first(); if (! $doctor) { return redirect()->to(site_url('/'))->with('error', 'Doctor profile not found.'); } $appointment = $appointmentModel->find($appointmentId); if (! $appointment || (int) $appointment['doctor_id'] !== (int) $doctor['id']) { return redirect()->back()->with('error', 'Invalid appointment.'); } $status = AppointmentModel::normalizeStatus($status); $appointmentModel->update($appointmentId, ['status' => $status]); return redirect()->back()->with('success', 'Appointment updated.'); } }