Doctor_dashboard

This commit is contained in:
Sayan Das 2026-04-01 19:30:56 +05:30
parent 3f7b30565d
commit 3760875a3d
5 changed files with 206 additions and 20 deletions

View File

@ -5,6 +5,7 @@ namespace App\Controllers;
use App\Models\AppointmentModel;
use App\Models\DoctorModel;
use CodeIgniter\HTTP\RedirectResponse;
use CodeIgniter\HTTP\ResponseInterface;
class Doctor extends BaseController
{
@ -55,7 +56,7 @@ class Doctor extends BaseController
if ($this->request->is('post')) {
$rules = [
'specialization' => 'required|min_length[2]|max_length[191]',
'experience' => 'permit_empty|max_length[100]',
'experience' => 'required|max_length[100]',
'fees' => 'permit_empty|decimal',
'available_from' => 'permit_empty',
'available_to' => 'permit_empty',
@ -85,7 +86,7 @@ class Doctor extends BaseController
return view('doctor/profile', ['doctor' => $doctor]);
}
public function accept($id): RedirectResponse
public function accept($id): ResponseInterface
{
if ($r = $this->requireRole('doctor')) {
return $r;
@ -98,7 +99,7 @@ class Doctor extends BaseController
return $this->updateAppointmentStatus((int) $id, 'approved');
}
public function reject($id): RedirectResponse
public function reject($id): ResponseInterface
{
if ($r = $this->requireRole('doctor')) {
return $r;
@ -131,6 +132,7 @@ class Doctor extends BaseController
return redirect()->back()->with('error', 'Invalid appointment.');
}
$status = \App\Models\AppointmentModel::normalizeStatus($status);
$appointmentModel->update($appointmentId, ['status' => $status]);
return redirect()->back()->with('success', 'Appointment updated.');

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Add doctor</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="<?= base_url('css/app.css') ?>">
</head>
<body class="app-body app-page--admin">
<?php $validationErrors = validation_errors(); ?>
<div class="container py-5" style="max-width: 560px;">
<h2 class="text-center mb-4 app-heading">Add doctor</h2>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger app-alert text-center"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<form method="post" action="<?= base_url('admin/doctors/add') ?>" class="app-form card app-card-dashboard p-4" novalidate>
<?= csrf_field() ?>
<div class="mb-3">
<label class="form-label" for="name">Full name</label>
<input type="text" name="name" id="name" value="<?= esc(old('name')) ?>"
class="form-control <?= isset($validationErrors['name']) ? 'is-invalid' : '' ?>">
<?= validation_show_error('name') ?>
</div>
<div class="mb-3">
<label class="form-label" for="email">Email (login)</label>
<input type="text" name="email" id="email" value="<?= esc(old('email')) ?>"
class="form-control <?= isset($validationErrors['email']) ? 'is-invalid' : '' ?>" autocomplete="off">
<?= validation_show_error('email') ?>
</div>
<div class="mb-3">
<label class="form-label" for="password"> Password</label>
<input type="password" name="password" id="password"
class="form-control <?= isset($validationErrors['password']) ? 'is-invalid' : '' ?>" autocomplete="new-password">
<?= validation_show_error('password') ?>
</div>
<div class="mb-3">
<label class="form-label" for="specialization">Specialization</label>
<input type="text" name="specialization" id="specialization" value="<?= esc(old('specialization')) ?>"
class="form-control <?= isset($validationErrors['specialization']) ? 'is-invalid' : '' ?>"
placeholder="e.g. Cardiology">
<?= validation_show_error('specialization') ?>
</div>
<div class="mb-3">
<label class="form-label" for="experience">Experience (optional)</label>
<input type="text" name="experience" id="experience" value="<?= esc(old('experience')) ?>"
class="form-control"
placeholder="e.g. 10 years">
<?= validation_show_error('experience') ?>
</div>
<div class="mb-3">
<label class="form-label" for="fees">Consultation fee (optional)</label>
<input type="number" name="fees" id="fees" value="<?= esc(old('fees')) ?>"
class="form-control"
placeholder="e.g. 500.00" step="0.01" min="0">
<?= validation_show_error('fees') ?>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label" for="available_from">Available from</label>
<input type="time" name="available_from" id="available_from" value="<?= esc(old('available_from')) ?>"
class="form-control <?= isset($validationErrors['available_from']) ? 'is-invalid' : '' ?>">
<?= validation_show_error('available_from') ?>
</div>
<div class="col-md-6 mb-3">
<label class="form-label" for="available_to">Available to</label>
<input type="time" name="available_to" id="available_to" value="<?= esc(old('available_to')) ?>"
class="form-control <?= isset($validationErrors['available_to']) ? 'is-invalid' : '' ?>">
<?= validation_show_error('available_to') ?>
</div>
</div>
<div class="d-flex flex-wrap gap-2 justify-content-between mt-4">
<a href="<?= base_url('admin/dashboard') ?>" class="btn btn-outline-secondary rounded-pill px-4">Cancel</a>
<button type="submit" class="btn btn-app-primary px-4">Create doctor</button>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Doctors</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="<?= base_url('css/app.css') ?>">
</head>
<body class="app-body app-page--admin">
<div class="container py-5">
<h2 class="text-center mb-4 app-heading">Doctors</h2>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success app-alert text-center"><?= esc(session()->getFlashdata('success')) ?></div>
<?php endif; ?>
<?php if (session()->getFlashdata('error')): ?>
<div class="alert alert-danger app-alert text-center"><?= esc(session()->getFlashdata('error')) ?></div>
<?php endif; ?>
<div class="text-center mb-4">
<a href="<?= base_url('admin/doctors/add') ?>" class="btn btn-app-primary">Add doctor</a>
</div>
<div class="app-table-wrap">
<table class="table table-bordered table-hover text-center align-middle">
<thead>
<tr>
<th>Sl No</th>
<th>Name</th>
<th>Specialization</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php $i = 1; ?>
<?php foreach ($doctors as $doc): ?>
<tr>
<td><?= $i++ ?></td>
<td><?= esc($doc->name) ?></td>
<td><?= esc($doc->specialization ?? 'N/A') ?></td>
<td>
<a href="<?= base_url('admin/deleteDoctor/' . $doc->id) ?>"
class="btn btn-outline-danger btn-sm rounded-pill px-3"
onclick="return confirm('Delete this doctor?');">
Delete
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div class="text-center mt-4">
<a href="<?= base_url('admin/dashboard') ?>" class="btn btn-app-outline px-4">Back to dashboard</a>
</div>
</div>
</body>
</html>

View File

@ -37,14 +37,27 @@
<p class="mb-3 small text-muted"> <?= esc($a->appointment_time) ?></p>
<p class="mb-3">
<span class="badge
<?= $a->status == 'pending' ? 'bg-warning text-dark' : '' ?>
<?= $a->status == 'approved' ? 'bg-success' : '' ?>
<?= $a->status == 'rejected' ? 'bg-danger' : '' ?>">
<?= esc(ucfirst((string) $a->status)) ?>
</span>
<?php
$st = trim((string) $a->status);
if ($st === '') {
$st = 'pending';
} elseif ($st === 'confirmed') {
$st = 'approved';
} elseif ($st === 'cancelled') {
$st = 'rejected';
}
$badgeClass = match ($st) {
'pending' => 'bg-warning text-dark',
'approved' => 'bg-success',
'rejected' => 'bg-danger',
default => 'bg-secondary',
};
?>
<span class="badge <?= $badgeClass ?>"><?= esc(ucfirst($st)) ?></span>
</p>
<?php if ($st === 'pending'): ?>
<div class="d-flex gap-2 flex-wrap">
<form method="post" action="<?= base_url('doctor/appointment/' . $a->id . '/accept') ?>" class="d-inline">
<?= csrf_field() ?>
@ -55,6 +68,7 @@
<button type="submit" class="btn btn-outline-danger btn-sm rounded-pill px-3">Reject</button>
</form>
</div>
<?php endif; ?>
</div>

View File

@ -51,7 +51,15 @@
<td><?= esc($ap->appointment_time) ?></td>
<td>
<?php
$st = (string) $ap->status;
$st = trim((string) $ap->status);
if ($st === '') {
$st = 'pending';
} elseif ($st === 'confirmed') {
$st = 'approved';
} elseif ($st === 'cancelled') {
$st = 'rejected';
}
$badgeClass = match ($st) {
'pending' => 'bg-warning text-dark',
'approved' => 'bg-success',