Fix Superuser User Management and Refactor Dashboard Layouts
- Refactor 'app/Views/superuser/users.php' to fix user creation/editing logic using Alpine.js. - Ensure efficient form state management (userid, username, password handling) in user modal. - Standardize dashboard layouts and script initialization (window.BASEURL) across 'admin', 'cs', 'lab', 'phlebo', and 'superuser' main views. - Remove redundant 'app/Views/admin/users.php' to consolidate user management.
This commit is contained in:
parent
13591da5b4
commit
02762bb355
120
CLAUDE.md
Normal file
120
CLAUDE.md
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a **CodeIgniter 4** PHP application for laboratory management (GDC CMOD - Laboratory Request Management System). It handles specimen collection tracking, request validation, and result management with role-based access control.
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run PHP built-in server (from project root)
|
||||||
|
php spark serve
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
composer test
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** This is a Windows-based deployment using IIS/XAMPP. For production, configure a virtual host pointing to the `public/` folder.
|
||||||
|
|
||||||
|
## Database Configuration
|
||||||
|
|
||||||
|
- **Primary DB:** SQL Server (`GDC_CMOD.dbo`) via Microsoft ODBC Driver (MSOLEDBSQL)
|
||||||
|
- **Legacy DB:** Firebird/InterBase (`GLENEAGLES` via ODBC) for patient data
|
||||||
|
- **Connection:** `\Config\Database::connect()` returns MySQLi connection
|
||||||
|
- **No CI4 Models** - uses raw SQL queries via `Database::connect()`
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Role-Based Access Control (RBAC)
|
||||||
|
|
||||||
|
| Role ID | Name | Route Prefix | Permissions |
|
||||||
|
|---------|------|--------------|-------------|
|
||||||
|
| 0 | Superuser | `/superuser` | Full access + Users CRUD |
|
||||||
|
| 1 | Admin | `/admin` | Full access + Users CRUD |
|
||||||
|
| 2 | Lab | `/lab` | Request validation, Sample collection |
|
||||||
|
| 3 | Phlebo | `/phlebo` | Request validation, Sample collection |
|
||||||
|
| 4 | CS | `/cs` | Request validation, Sample collection |
|
||||||
|
|
||||||
|
### Authentication Flow
|
||||||
|
|
||||||
|
1. `Auth::login()` - Verifies credentials against `GDC_CMOD.dbo.USERS`, sets session
|
||||||
|
2. `RoleFilter` - Checks `session()->get('isLoggedIn')` and role ID
|
||||||
|
3. `GuestFilter` - Redirects logged-in users to role-based dashboard
|
||||||
|
|
||||||
|
### Key Database Tables
|
||||||
|
|
||||||
|
- `GDC_CMOD.dbo.USERS` - Users with `USERID`, `USERROLEID`, `PASSWORD`
|
||||||
|
- `GDC_CMOD.dbo.CM_REQUESTS` - Validation tracking (`ISVAL1`, `ISVAL2`, validation users/dates)
|
||||||
|
- `GDC_CMOD.dbo.TUBES` - Sample collection status
|
||||||
|
- `GDC_CMOD.dbo.V_DASHBOARD_DEV` - Dashboard data view
|
||||||
|
- `glendb.dbo.*` - Legacy Firebird patient data
|
||||||
|
|
||||||
|
### Request Validation (Dual-Level)
|
||||||
|
|
||||||
|
Validation requires 2 different users to validate the same request:
|
||||||
|
1. First validation sets `ISVAL1=1`, `VAL1USER`, `VAL1DATE`
|
||||||
|
2. Second validation (different user) sets `ISVAL2=1`, `VAL2USER`, `VAL2DATE`
|
||||||
|
|
||||||
|
## Code Conventions
|
||||||
|
|
||||||
|
### Controllers
|
||||||
|
- All extend `BaseController` (which extends `CodeIgniter\Controller`)
|
||||||
|
- Use `ResponseTrait` for JSON APIs
|
||||||
|
- Raw SQL queries via `\Config\Database::connect()->query()`
|
||||||
|
|
||||||
|
### Routing Pattern
|
||||||
|
|
||||||
|
```php
|
||||||
|
$routes->group('prefix', ['filter' => 'role:N'], function($routes) {
|
||||||
|
$routes->get('', 'Controller::index');
|
||||||
|
$routes->get('api/resource', 'Controller::method');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Session Structure
|
||||||
|
|
||||||
|
```php
|
||||||
|
session()->set([
|
||||||
|
'isLoggedIn' => true,
|
||||||
|
'userid' => (string) $user['USERID'],
|
||||||
|
'userroleid' => (int) $user['USERROLEID'],
|
||||||
|
'userrole' => (string) $role,
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important Routes
|
||||||
|
|
||||||
|
| Route | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `/login`, `/logout` | Authentication |
|
||||||
|
| `/label/coll/:accessnumber` | Zebra printer label (public) |
|
||||||
|
| `/api/requests` | Dashboard data (date-filtered) |
|
||||||
|
| `/api/requests/validate/:accessnumber` | Dual-level validation |
|
||||||
|
| `/api/samples/collect/:accessnumber` | Mark sample collected |
|
||||||
|
| `/api/samples/receive/:accessnumber` | Mark sample received (Admin/Superuser only) |
|
||||||
|
|
||||||
|
## Frontend Stack
|
||||||
|
|
||||||
|
- TailwindCSS + DaisyUI 5 (CDN)
|
||||||
|
- Alpine.js for reactivity
|
||||||
|
- Font Awesome 7 for icons
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### JSON API Response
|
||||||
|
```php
|
||||||
|
return $this->response->setJSON(['status' => 'success', 'data' => $result]);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database Query
|
||||||
|
```php
|
||||||
|
$db = \Config\Database::connect();
|
||||||
|
$result = $db->query("SELECT * FROM table WHERE col = ?", [$value])->getResultArray();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Date Formatting from SQL Server
|
||||||
|
```php
|
||||||
|
$row['DATE_COLUMN'] = date('Y-m-d H:i', strtotime($row['DATE_COLUMN']));
|
||||||
|
```
|
||||||
@ -77,3 +77,18 @@ defined('EXIT_USER_INPUT') || define('EXIT_USER_INPUT', 7); // invalid u
|
|||||||
defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error
|
defined('EXIT_DATABASE') || define('EXIT_DATABASE', 8); // database error
|
||||||
defined('EXIT__AUTO_MIN') || define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
defined('EXIT__AUTO_MIN') || define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
||||||
defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
defined('EXIT__AUTO_MAX') || define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Role Names
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Mapping of role IDs to role names for the application.
|
||||||
|
*/
|
||||||
|
defined('ROLE_NAMES') || define('ROLE_NAMES', [
|
||||||
|
0 => 'Superuser',
|
||||||
|
1 => 'Admin',
|
||||||
|
2 => 'Lab Analyst',
|
||||||
|
3 => 'Phlebotomist',
|
||||||
|
4 => 'Customer Service',
|
||||||
|
]);
|
||||||
|
|||||||
@ -11,72 +11,74 @@ $routes->get('/unauthorized', 'ErrorPage::unauthorized');
|
|||||||
|
|
||||||
|
|
||||||
$routes->get('/', 'Home::index');
|
$routes->get('/', 'Home::index');
|
||||||
$routes->get('/login', 'Auth::loginPage', ['filter' => 'guest']);
|
$routes->get('/login', 'AuthController::loginPage', ['filter' => 'guest']);
|
||||||
$routes->post('/login', 'Auth::login', ['filter' => 'guest']);
|
$routes->post('/login', 'AuthController::login', ['filter' => 'guest']);
|
||||||
$routes->get('/logout', 'Auth::logout');
|
$routes->get('/logout', 'AuthController::logout');
|
||||||
$routes->patch('/setPassword', 'Auth::setPassword');
|
$routes->patch('/setPassword', 'AuthController::setPassword');
|
||||||
|
|
||||||
$routes->get('label/coll/(:any)', 'Label::coll/$1');
|
$routes->get('label/coll/(:any)', 'LabelController::coll/$1');
|
||||||
$routes->get('label/dispatch/(:any)/(:any)', 'Label::dispatch/$1/$2');
|
$routes->get('label/dispatch/(:any)/(:any)', 'LabelController::dispatch/$1/$2');
|
||||||
$routes->get('label/all/(:any)', 'Label::print_all/$1');
|
$routes->get('label/all/(:any)', 'LabelController::print_all/$1');
|
||||||
|
|
||||||
|
|
||||||
|
// --- API Group ---
|
||||||
|
$routes->group('api', function ($routes) {
|
||||||
|
|
||||||
|
// Users Management - Only Superuser (0) and Admin (1)
|
||||||
|
$routes->group('users', ['filter' => 'role:0,1'], function ($routes) {
|
||||||
|
$routes->get('', 'UsersController::index');
|
||||||
|
$routes->post('', 'UsersController::create');
|
||||||
|
$routes->patch('(:any)', 'UsersController::update/$1');
|
||||||
|
$routes->delete('(:any)', 'UsersController::delete/$1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Requests - All Roles (0,1,2,3,4)
|
||||||
|
$routes->group('requests', ['filter' => 'role:0,1,2,3,4'], function ($routes) {
|
||||||
|
$routes->get('', 'RequestsController::index');
|
||||||
|
$routes->post('validate/(:any)', 'RequestsController::val/$1');
|
||||||
|
$routes->delete('validate/(:any)', 'RequestsController::unval/$1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Samples
|
||||||
|
$routes->group('samples', function ($routes) {
|
||||||
|
// Collect & Show - All Roles
|
||||||
|
$routes->group('', ['filter' => 'role:0,1,2,3,4'], function ($routes) {
|
||||||
|
$routes->post('collect/(:any)', 'SamplesController::collect/$1');
|
||||||
|
$routes->get('(:any)', 'SamplesController::show/$1');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Uncollect & Unreceive - Only Superuser (0) and Admin (1)
|
||||||
|
$routes->group('', ['filter' => 'role:0,1'], function ($routes) {
|
||||||
|
$routes->delete('collect/(:any)', 'SamplesController::uncollect/$1');
|
||||||
|
$routes->delete('receive/(:any)', 'SamplesController::unreceive/$1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --- Page Routes ---
|
||||||
|
|
||||||
$routes->group('superuser', ['filter' => 'role:0'], function ($routes) {
|
$routes->group('superuser', ['filter' => 'role:0'], function ($routes) {
|
||||||
$routes->get('', 'Superuser::index');
|
$routes->get('', 'Pages\SuperuserController::index');
|
||||||
$routes->get('users', 'Superuser::users');
|
$routes->get('users', 'Pages\SuperuserController::users');
|
||||||
$routes->get('api/users', 'Users::index');
|
|
||||||
$routes->post('api/users', 'Users::create');
|
|
||||||
$routes->patch('api/users/(:any)', 'Users::update/$1');
|
|
||||||
$routes->delete('api/users/(:any)', 'Users::delete/$1');
|
|
||||||
$routes->get('api/requests', 'Requests::index');
|
|
||||||
$routes->post('api/requests/validate/(:any)', 'Requests::val/$1');
|
|
||||||
$routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1');
|
|
||||||
$routes->post('api/samples/collect/(:any)', 'Samples::collect/$1');
|
|
||||||
$routes->delete('api/samples/collect/(:any)', 'Samples::uncollect/$1');
|
|
||||||
$routes->delete('api/samples/receive/(:any)', 'Samples::unreceive/$1');
|
|
||||||
$routes->get('api/samples/(:any)', 'Samples::show/$1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$routes->group('admin', ['filter' => 'role:1'], function ($routes) {
|
$routes->group('admin', ['filter' => 'role:1'], function ($routes) {
|
||||||
$routes->get('', 'Admin::index');
|
$routes->get('', 'Pages\AdminController::index');
|
||||||
$routes->get('users', 'Admin::users');
|
$routes->get('users', 'Pages\AdminController::users');
|
||||||
$routes->get('api/users', 'Users::index');
|
|
||||||
$routes->post('api/users', 'Users::create');
|
|
||||||
$routes->patch('api/users/(:any)', 'Users::update/$1');
|
|
||||||
$routes->delete('api/users/(:any)', 'Users::delete/$1');
|
|
||||||
$routes->get('api/requests', 'Requests::index');
|
|
||||||
$routes->post('api/requests/validate/(:any)', 'Requests::val/$1');
|
|
||||||
$routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1');
|
|
||||||
$routes->post('api/samples/collect/(:any)', 'Samples::collect/$1');
|
|
||||||
$routes->delete('api/samples/collect/(:any)', 'Samples::uncollect/$1');
|
|
||||||
$routes->delete('api/samples/receive/(:any)', 'Samples::unreceive/$1');
|
|
||||||
$routes->get('api/samples/(:any)', 'Samples::show/$1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$routes->group('lab', ['filter' => 'role:2'], function ($routes) {
|
$routes->group('lab', ['filter' => 'role:2'], function ($routes) {
|
||||||
$routes->get('', 'Lab::index');
|
$routes->get('', 'Pages\LabController::index');
|
||||||
$routes->get('api/requests', 'Requests::index');
|
|
||||||
$routes->post('api/requests/validate/(:any)', 'Requests::val/$1');
|
|
||||||
$routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1');
|
|
||||||
$routes->post('api/samples/collect/(:any)', 'Samples::collect/$1');
|
|
||||||
$routes->get('api/samples/(:any)', 'Samples::show/$1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$routes->group('phlebo', ['filter' => 'role:3'], function ($routes) {
|
$routes->group('phlebo', ['filter' => 'role:3'], function ($routes) {
|
||||||
$routes->get('', 'Phlebotomist::index');
|
$routes->get('', 'Pages\PhlebotomistController::index');
|
||||||
$routes->get('api/requests', 'Requests::index');
|
|
||||||
$routes->post('api/requests/validate/(:any)', 'Requests::val/$1');
|
|
||||||
$routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1');
|
|
||||||
$routes->post('api/samples/collect/(:any)', 'Samples::collect/$1');
|
|
||||||
$routes->get('api/samples/(:any)', 'Samples::show/$1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$routes->group('cs', ['filter' => 'role:4'], function ($routes) {
|
$routes->group('cs', ['filter' => 'role:4'], function ($routes) {
|
||||||
$routes->get('', 'Cs::index');
|
$routes->get('', 'Pages\CsController::index');
|
||||||
$routes->get('api/requests', 'Requests::index');
|
|
||||||
$routes->post('api/requests/validate/(:any)', 'Requests::val/$1');
|
|
||||||
$routes->delete('api/requests/validate/(:any)', 'Requests::unval/$1');
|
|
||||||
$routes->post('api/samples/collect/(:any)', 'Samples::collect/$1');
|
|
||||||
$routes->get('api/samples/(:any)', 'Samples::show/$1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$routes->get('/dummypage', 'Home::dummyPage');
|
$routes->get('/dummypage', 'Home::dummyPage');
|
||||||
|
|||||||
@ -4,13 +4,16 @@ namespace App\Controllers;
|
|||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Auth extends BaseController {
|
class AuthController extends BaseController
|
||||||
|
{
|
||||||
|
|
||||||
public function loginPage() {
|
public function loginPage()
|
||||||
|
{
|
||||||
return view("login");
|
return view("login");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login() {
|
public function login()
|
||||||
|
{
|
||||||
helper(['form', 'url']);
|
helper(['form', 'url']);
|
||||||
$session = session();
|
$session = session();
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
@ -23,26 +26,8 @@ class Auth extends BaseController {
|
|||||||
|
|
||||||
if ($user && !empty($user['PASSWORD']) && password_verify($password, $user['PASSWORD'])) {
|
if ($user && !empty($user['PASSWORD']) && password_verify($password, $user['PASSWORD'])) {
|
||||||
|
|
||||||
switch ((int)$user['USERROLEID']) {
|
$roleId = (int) $user['USERROLEID'];
|
||||||
case 0:
|
$role = ROLE_NAMES[$roleId] ?? '';
|
||||||
$role = 'Superuser';
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
$role = 'Admin';
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
$role = 'Lab Analyst';
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
$role = 'Phlebotomist';
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
$role = 'Customer Service';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$role = '';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$session->set([
|
$session->set([
|
||||||
'isLoggedIn' => true,
|
'isLoggedIn' => true,
|
||||||
@ -71,13 +56,15 @@ class Auth extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logout() {
|
public function logout()
|
||||||
|
{
|
||||||
$session = session();
|
$session = session();
|
||||||
$session->destroy();
|
$session->destroy();
|
||||||
return redirect()->to('login');
|
return redirect()->to('login');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPassword() {
|
public function setPassword()
|
||||||
|
{
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$userid = $input['userid'];
|
$userid = $input['userid'];
|
||||||
$password = $input['password'];
|
$password = $input['password'];
|
||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
class Label extends BaseController {
|
class LabelController extends BaseController
|
||||||
public function coll($reqnum) {
|
{
|
||||||
|
public function coll($reqnum)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
//$reqnum = str_pad($reqnum, 10, 0, STR_PAD_LEFT);
|
//$reqnum = str_pad($reqnum, 10, 0, STR_PAD_LEFT);
|
||||||
$sql = "select p.PATNUMBER,
|
$sql = "select p.PATNUMBER,
|
||||||
@ -65,7 +67,8 @@ P1\n]";
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dispatch($reqnum, $samid) {
|
public function dispatch($reqnum, $samid)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$sql = "select p.PATNUMBER,
|
$sql = "select p.PATNUMBER,
|
||||||
[Name] = case
|
[Name] = case
|
||||||
@ -109,7 +112,9 @@ P1\n]";
|
|||||||
$samptext = $row['SHORTTEXT'];
|
$samptext = $row['SHORTTEXT'];
|
||||||
$tests = $row['TESTS'];
|
$tests = $row['TESTS'];
|
||||||
$tests1 = $row['TESTS1'];
|
$tests1 = $row['TESTS1'];
|
||||||
if($tests == '') {$tests = $tests1;}
|
if ($tests == '') {
|
||||||
|
$tests = $tests1;
|
||||||
|
}
|
||||||
$tubeid = $sampcode . substr("$reqnum", 5, 5);
|
$tubeid = $sampcode . substr("$reqnum", 5, 5);
|
||||||
$date = date("d/M/Y H:i");
|
$date = date("d/M/Y H:i");
|
||||||
|
|
||||||
@ -139,7 +144,8 @@ P1
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function print_all($accessnumber) {
|
public function print_all($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$this->coll($accessnumber);
|
$this->coll($accessnumber);
|
||||||
$sql = "select SAMPCODE from GDC_CMOD.dbo.v_sp_reqtube where SP_ACCESSNUMBER='$accessnumber'";
|
$sql = "select SAMPCODE from GDC_CMOD.dbo.v_sp_reqtube where SP_ACCESSNUMBER='$accessnumber'";
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers\Pages;
|
||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Admin extends BaseController {
|
class AdminController extends BaseController {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
helper(['url', 'form', 'text']);
|
helper(['url', 'form', 'text']);
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers\Pages;
|
||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Cs extends BaseController {
|
class CsController extends BaseController {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
helper(['url', 'form', 'text']);
|
helper(['url', 'form', 'text']);
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers\Pages;
|
||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Lab extends BaseController {
|
class LabController extends BaseController {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
helper(['url', 'form', 'text']);
|
helper(['url', 'form', 'text']);
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers\Pages;
|
||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Phlebotomist extends BaseController {
|
class PhlebotomistController extends BaseController {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
helper(['url', 'form', 'text']);
|
helper(['url', 'form', 'text']);
|
||||||
@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers\Pages;
|
||||||
|
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Superuser extends BaseController {
|
class SuperuserController extends BaseController {
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
helper(['url', 'form', 'text']);
|
helper(['url', 'form', 'text']);
|
||||||
@ -3,10 +3,12 @@ namespace App\Controllers;
|
|||||||
use CodeIgniter\API\ResponseTrait;
|
use CodeIgniter\API\ResponseTrait;
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Requests extends BaseController {
|
class RequestsController extends BaseController
|
||||||
|
{
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
public function index() {
|
public function index()
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$date1 = $this->request->getGet('date1');
|
$date1 = $this->request->getGet('date1');
|
||||||
$date2 = $this->request->getGet('date2');
|
$date2 = $this->request->getGet('date2');
|
||||||
@ -25,7 +27,8 @@ class Requests extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function show($accessnumber) {
|
public function show($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$data['accessnumber'] = $accessnumber;
|
$data['accessnumber'] = $accessnumber;
|
||||||
$sql = "SELECT d.STATS, r.* FROM GDC_CMOD.dbo.V_DASHBOARD_DEV d
|
$sql = "SELECT d.STATS, r.* FROM GDC_CMOD.dbo.V_DASHBOARD_DEV d
|
||||||
@ -41,14 +44,17 @@ class Requests extends BaseController {
|
|||||||
return view('admin/modal_request', $data);
|
return view('admin/modal_request', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showUnval($accessnumber) {
|
public function showUnval($accessnumber)
|
||||||
|
{
|
||||||
$data['accessnumber'] = $accessnumber;
|
$data['accessnumber'] = $accessnumber;
|
||||||
return view('admin/modal_unvalidate', $data);
|
return view('admin/modal_unvalidate', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unval($accessnumber) {
|
public function unval($accessnumber)
|
||||||
|
{
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$userid = $input['userid'];
|
// Securely get userid from session
|
||||||
|
$userid = session('userid');
|
||||||
$comment = $input['comment'];
|
$comment = $input['comment'];
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=null, VAL1USER=null, VAL1DATE=null, ISVAL2=null, VAL2USER=null, VAL2DATE=null,
|
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL1=null, VAL1USER=null, VAL1DATE=null, ISVAL2=null, VAL2USER=null, VAL2DATE=null,
|
||||||
@ -59,9 +65,11 @@ class Requests extends BaseController {
|
|||||||
return $this->response->setJSON($data);
|
return $this->response->setJSON($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function val($accessnumber) {
|
public function val($accessnumber)
|
||||||
|
{
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$userid = $input['userid'];
|
// Securely get userid from session
|
||||||
|
$userid = session('userid');
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$sql = "select * from GDC_CMOD.dbo.CM_REQUESTS where ACCESSNUMBER='$accessnumber'";
|
$sql = "select * from GDC_CMOD.dbo.CM_REQUESTS where ACCESSNUMBER='$accessnumber'";
|
||||||
$result = $db->query($sql)->getResultArray();
|
$result = $db->query($sql)->getResultArray();
|
||||||
@ -76,8 +84,9 @@ class Requests extends BaseController {
|
|||||||
$isval2 = $row['ISVAL2'];
|
$isval2 = $row['ISVAL2'];
|
||||||
$val1user = $row['VAL1USER'];
|
$val1user = $row['VAL1USER'];
|
||||||
if ($isval1 == 1) {
|
if ($isval1 == 1) {
|
||||||
if ( $isval2 == 1 ) { return $this->response->setJSON(['message'=> 'validation done, not updating anything']); }
|
if ($isval2 == 1) {
|
||||||
else {
|
return $this->response->setJSON(['message' => 'validation done, not updating anything']);
|
||||||
|
} else {
|
||||||
if ($val1user != $userid) {
|
if ($val1user != $userid) {
|
||||||
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL2=1, VAL2USER='$userid', VAL2DATE=GETDATE() where ACCESSNUMBER='$accessnumber'";
|
$sql = "update GDC_CMOD.dbo.CM_REQUESTS set ISVAL2=1, VAL2USER='$userid', VAL2DATE=GETDATE() where ACCESSNUMBER='$accessnumber'";
|
||||||
$data['val'] = 2;
|
$data['val'] = 2;
|
||||||
@ -3,10 +3,12 @@ namespace App\Controllers;
|
|||||||
use CodeIgniter\API\ResponseTrait;
|
use CodeIgniter\API\ResponseTrait;
|
||||||
use App\Controllers\BaseController;
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
class Samples extends BaseController {
|
class SamplesController extends BaseController
|
||||||
|
{
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
public function show($accessnumber) {
|
public function show($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
|
|
||||||
$sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name],
|
$sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name],
|
||||||
@ -60,11 +62,12 @@ class Samples extends BaseController {
|
|||||||
return $this->response->setJSON($resp);
|
return $this->response->setJSON($resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function collect($accessnumber) {
|
public function collect($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$samplenumber = $input['samplenumber'];
|
$samplenumber = $input['samplenumber'];
|
||||||
$userid = $input['userid'];
|
$userid = session('userid');
|
||||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
||||||
$db->query($sql);
|
$db->query($sql);
|
||||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||||
@ -73,11 +76,12 @@ class Samples extends BaseController {
|
|||||||
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
|
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function uncollect($accessnumber) {
|
public function uncollect($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$samplenumber = $input['samplenumber'];
|
$samplenumber = $input['samplenumber'];
|
||||||
$userid = $input['userid'];
|
$userid = session('userid');
|
||||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='0', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='0', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
||||||
$db->query($sql);
|
$db->query($sql);
|
||||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||||
@ -86,7 +90,8 @@ class Samples extends BaseController {
|
|||||||
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
|
return $this->respondCreated(['status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber"], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unreceive($accessnumber) {
|
public function unreceive($accessnumber)
|
||||||
|
{
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$input = $this->request->getJSON(true);
|
$input = $this->request->getJSON(true);
|
||||||
$samplenumber = $input['samplenumber'];
|
$samplenumber = $input['samplenumber'];
|
||||||
@ -113,7 +118,9 @@ class Samples extends BaseController {
|
|||||||
$conn = odbc_connect('GLENEAGLES', '', '');
|
$conn = odbc_connect('GLENEAGLES', '', '');
|
||||||
$sql = "UPDATE TDL_ORDERDT SET ODD_NRECEIVED=NULL , ODD_DTRECEIVE=NULL WHERE ODR_CNOLAB='$hon' and ODD_CPRODUCTCODE IN ($his_test)";
|
$sql = "UPDATE TDL_ORDERDT SET ODD_NRECEIVED=NULL , ODD_DTRECEIVE=NULL WHERE ODR_CNOLAB='$hon' and ODD_CPRODUCTCODE IN ($his_test)";
|
||||||
$rs = odbc_exec($conn, $sql);
|
$rs = odbc_exec($conn, $sql);
|
||||||
if (!$rs) {exit("Error in Update FB");}
|
if (!$rs) {
|
||||||
|
exit("Error in Update FB");
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' ";
|
$sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' ";
|
||||||
$db->query($sql);
|
$db->query($sql);
|
||||||
@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace App\Controllers;
|
|
||||||
use CodeIgniter\API\ResponseTrait;
|
|
||||||
use App\Controllers\BaseController;
|
|
||||||
|
|
||||||
// Users Management
|
|
||||||
class Users extends BaseController {
|
|
||||||
use ResponseTrait;
|
|
||||||
protected $db;
|
|
||||||
|
|
||||||
public function __construct() {
|
|
||||||
$this->db = \Config\Database::connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index() {
|
|
||||||
$sql = "select u.USERID, u.USERLEVEL from GDC_CMOD.dbo.USERS u
|
|
||||||
left join glendb.dbo.USERS u1 on u1.USERID=u.USERID
|
|
||||||
where u1.LOCKEDACCOUNT is null";
|
|
||||||
$query = $this->db->query($sql);
|
|
||||||
$results = $query->getResultArray();
|
|
||||||
$data['data'] = $results;
|
|
||||||
|
|
||||||
return $this->respond(['data' => $results]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create() {
|
|
||||||
$input = $this->request->getJSON(true);
|
|
||||||
$userid = $input['userid'];
|
|
||||||
$userlevel = $input['userlevel'];
|
|
||||||
$password = $input['password'];
|
|
||||||
$password_2 = $input['password_2'];
|
|
||||||
|
|
||||||
if ($password != $password_2) {
|
|
||||||
return $this->response->setJSON(['message'=> 'Password not the same']);
|
|
||||||
}
|
|
||||||
if ( strlen($password) < 3 ) {
|
|
||||||
return $this->response->setJSON(['message'=> 'Password must be more than 2 characters']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = $this->db->query("SELECT USERID FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]);
|
|
||||||
$query = $sql->getRowArray();
|
|
||||||
if ($query != null) {
|
|
||||||
return $this->response->setJSON(['message'=> 'Userid already exists']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
|
||||||
|
|
||||||
$this->db->transBegin();
|
|
||||||
try {
|
|
||||||
$sqlInsert = "
|
|
||||||
INSERT INTO gdc_cmod.dbo.USERS (USERID, USERLEVEL, PASSWORD)
|
|
||||||
VALUES (?, ?, ?)
|
|
||||||
";
|
|
||||||
$this->db->query($sqlInsert, [$userid, $userlevel, $hashedPassword]);
|
|
||||||
|
|
||||||
$this->db->transCommit();
|
|
||||||
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
$this->db->transRollback();
|
|
||||||
return $this->response->setJSON(['message'=> 'Server error']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response->setJSON(['message'=> 'User '.$userid.' Berhasil ditambahkan!']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update($id = null) {
|
|
||||||
$input = $this->request->getJSON(true);
|
|
||||||
$userid = $input['userid'];
|
|
||||||
$userlevel = $input['userlevel'];
|
|
||||||
$password = $input['password'];
|
|
||||||
$password_2 = $input['password_2'];
|
|
||||||
|
|
||||||
if ( $password != '' || $password_2 != '') {
|
|
||||||
if ($password != $password_2) {
|
|
||||||
return $this->response->setJSON(['message'=> 'Password not the same']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
|
||||||
$sqlUpdate ="
|
|
||||||
UPDATE gdc_cmod.dbo.USERS
|
|
||||||
SET USERLEVEL = ?,
|
|
||||||
PASSWORD = ?
|
|
||||||
WHERE USERID = ?
|
|
||||||
";
|
|
||||||
$fullUpdate = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$sqlUpdate ="
|
|
||||||
UPDATE gdc_cmod.dbo.USERS
|
|
||||||
SET USERLEVEL = ?
|
|
||||||
WHERE USERID = ?
|
|
||||||
";
|
|
||||||
$fullUpdate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->transBegin();
|
|
||||||
try {
|
|
||||||
|
|
||||||
if ($fullUpdate) {
|
|
||||||
$this->db->query($sqlUpdate, [$userlevel, $hashedPassword, $userid]);
|
|
||||||
} else {
|
|
||||||
$this->db->query($sqlUpdate, [$userlevel, $userid]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->db->transCommit();
|
|
||||||
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
$this->db->transRollback();
|
|
||||||
return $this->response->setJSON(['message'=> 'Terjadi kesalahan pada server.']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->response->setJSON(['message'=> 'User '.$userid.' Berhasil Diupdate!']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
140
app/Controllers/UsersController.php
Normal file
140
app/Controllers/UsersController.php
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Controllers;
|
||||||
|
use CodeIgniter\API\ResponseTrait;
|
||||||
|
use App\Controllers\BaseController;
|
||||||
|
|
||||||
|
// Users Management
|
||||||
|
class UsersController extends BaseController
|
||||||
|
{
|
||||||
|
use ResponseTrait;
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->db = \Config\Database::connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$sql = "select u.USERID, u.USERROLEID, u.USERNAME from GDC_CMOD.dbo.USERS u
|
||||||
|
left join glendb.dbo.USERS u1 on u1.USERID=u.USERID
|
||||||
|
where u1.LOCKEDACCOUNT is null";
|
||||||
|
$query = $this->db->query($sql);
|
||||||
|
$results = $query->getResultArray();
|
||||||
|
$data['data'] = $results;
|
||||||
|
|
||||||
|
return $this->respond(['data' => $results]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
$input = $this->request->getJSON(true);
|
||||||
|
$userid = $input['userid'];
|
||||||
|
$userroleid = $input['userroleid'];
|
||||||
|
$password = $input['password'];
|
||||||
|
$password_2 = $input['password_2'];
|
||||||
|
|
||||||
|
if ($password != $password_2) {
|
||||||
|
return $this->response->setJSON(['message' => 'Password not the same']);
|
||||||
|
}
|
||||||
|
if (strlen($password) < 3) {
|
||||||
|
return $this->response->setJSON(['message' => 'Password must be more than 2 characters']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = $this->db->query("SELECT USERID FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]);
|
||||||
|
$query = $sql->getRowArray();
|
||||||
|
if ($query != null) {
|
||||||
|
return $this->response->setJSON(['message' => 'Userid already exists']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
$this->db->transBegin();
|
||||||
|
try {
|
||||||
|
$sqlInsert = "
|
||||||
|
INSERT INTO gdc_cmod.dbo.USERS (USERID, USERROLEID, PASSWORD)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
";
|
||||||
|
$this->db->query($sqlInsert, [$userid, $userroleid, $hashedPassword]);
|
||||||
|
|
||||||
|
$this->db->transCommit();
|
||||||
|
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$this->db->transRollback();
|
||||||
|
return $this->response->setJSON(['message' => 'Server error']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setJSON(['message' => 'User ' . $userid . ' Berhasil ditambahkan!']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id = null)
|
||||||
|
{
|
||||||
|
$input = $this->request->getJSON(true);
|
||||||
|
$userid = $input['userid'];
|
||||||
|
$userroleid = $input['userroleid'];
|
||||||
|
$password = $input['password'];
|
||||||
|
$password_2 = $input['password_2'];
|
||||||
|
|
||||||
|
if ($password != '' || $password_2 != '') {
|
||||||
|
if ($password != $password_2) {
|
||||||
|
return $this->response->setJSON(['message' => 'Password not the same']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
$sqlUpdate = "
|
||||||
|
UPDATE gdc_cmod.dbo.USERS
|
||||||
|
SET USERROLEID = ?,
|
||||||
|
PASSWORD = ?
|
||||||
|
WHERE USERID = ?
|
||||||
|
";
|
||||||
|
$fullUpdate = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$sqlUpdate = "
|
||||||
|
UPDATE gdc_cmod.dbo.USERS
|
||||||
|
SET USERROLEID = ?
|
||||||
|
WHERE USERID = ?
|
||||||
|
";
|
||||||
|
$fullUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->transBegin();
|
||||||
|
try {
|
||||||
|
|
||||||
|
if ($fullUpdate) {
|
||||||
|
$this->db->query($sqlUpdate, [$userroleid, $hashedPassword, $userid]);
|
||||||
|
} else {
|
||||||
|
$this->db->query($sqlUpdate, [$userroleid, $userid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->transCommit();
|
||||||
|
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$this->db->transRollback();
|
||||||
|
return $this->response->setJSON(['message' => 'Terjadi kesalahan pada server.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setJSON(['message' => 'User ' . $userid . ' Berhasil Diupdate!']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($id = null)
|
||||||
|
{
|
||||||
|
$this->db->transBegin();
|
||||||
|
try {
|
||||||
|
$sql = "DELETE FROM gdc_cmod.dbo.USERS WHERE USERID = ?";
|
||||||
|
$this->db->query($sql, [$id]);
|
||||||
|
|
||||||
|
if ($this->db->affectedRows() == 0) {
|
||||||
|
throw new \Exception('User not found or already deleted');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->transCommit();
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
$this->db->transRollback();
|
||||||
|
return $this->response->setStatusCode(500)->setJSON(['message' => 'Error deleting user: ' . $e->getMessage()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setJSON(['message' => 'User ' . $id . ' deleted successfully']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -28,20 +28,13 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-base-200 min-h-screen" x-data="main">
|
<body class="bg-base-200 min-h-screen" x-data="main">
|
||||||
<div class="drawer">
|
<div class="flex flex-col min-h-screen">
|
||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content flex flex-col min-h-screen">
|
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||||
<div class="flex-none">
|
|
||||||
<label for="main-drawer" aria-label="open sidebar" class="btn btn-square btn-ghost">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class='flex-1'>
|
<div class='flex-1'>
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
||||||
<i class="fa fa-cube"></i> CMOD <span
|
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">|
|
||||||
class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Admin Dashboard</span>
|
Admin Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -51,8 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-end">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
<span class="text-xl"><i class="fa fa-bars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ul tabindex="0"
|
||||||
|
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-lg border border-base-300">
|
||||||
|
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
||||||
|
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||||
|
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
||||||
|
<div class="divider my-1"></div>
|
||||||
|
<li><a href="<?= base_url('admin') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -64,32 +65,8 @@
|
|||||||
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="drawer-side z-50">
|
|
||||||
<label for="main-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
||||||
<ul class="menu bg-base-100 text-base-content min-h-full w-80 p-4 flex flex-col">
|
|
||||||
<!-- Sidebar content here -->
|
|
||||||
<li class="mb-4">
|
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
|
||||||
<i class="fa fa-cube"></i> CMOD
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="<?= base_url('admin') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
|
||||||
<li><a href="<?= base_url('admin/users') ?>"><i class="fa fa-users mr-2"></i> Users </a></li>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<li class="menu-title">Account</li>
|
|
||||||
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
|
||||||
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
|
||||||
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.BASEURL = "<?= base_url("admin"); ?>";
|
window.BASEURL = "<?= base_url(); ?>";
|
||||||
</script>
|
</script>
|
||||||
<?= $this->renderSection('script'); ?>
|
<?= $this->renderSection('script'); ?>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -1,269 +0,0 @@
|
|||||||
<?= $this->extend('admin/main'); ?>
|
|
||||||
|
|
||||||
<?= $this->section('content') ?>
|
|
||||||
<div x-data="users" class="contents">
|
|
||||||
<main class="p-4 flex-1 flex flex-col gap-2 max-w-6xl w-full mx-auto">
|
|
||||||
<div class="card bg-base-100 shadow-xl border border-base-200">
|
|
||||||
<div class="card-body p-4">
|
|
||||||
<div class="flex justify-between items-center mb-4">
|
|
||||||
<h2 class="text-2xl font-bold flex items-center gap-2 text-base-content">
|
|
||||||
<i class="fa fa-users text-primary"></i> User Management
|
|
||||||
</h2>
|
|
||||||
<button class="btn btn-primary btn-sm" @click="openUserModal('create')">
|
|
||||||
<i class="fa fa-plus"></i> Add User
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
|
||||||
<template x-if="isLoading">
|
|
||||||
<table class="table table-zebra w-full">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><div class="skeleton h-4 w-24"></div></th>
|
|
||||||
<th><div class="skeleton h-4 w-24"></div></th>
|
|
||||||
<th class="text-right"><div class="skeleton h-4 w-16 ml-auto"></div></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<template x-for="i in 5" :key="i">
|
|
||||||
<tr>
|
|
||||||
<td><div class="skeleton h-4 w-20"></div></td>
|
|
||||||
<td><div class="skeleton h-4 w-24"></div></td>
|
|
||||||
<td class="text-right"><div class="skeleton h-4 w-16 ml-auto"></div></td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
<template x-if="!isLoading && list.length">
|
|
||||||
<table class="table table-zebra w-full">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>User ID</th>
|
|
||||||
<th>Role/Level</th>
|
|
||||||
<th class="text-right">Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<template x-for="user in list" :key="user.USERID">
|
|
||||||
<tr>
|
|
||||||
<td class="font-bold" x-text="user.USERID"></td>
|
|
||||||
<td>
|
|
||||||
<span class="badge"
|
|
||||||
:class="getRoleClass(user.USERLEVEL)"
|
|
||||||
x-text="getRoleName(user.USERLEVEL)"></span>
|
|
||||||
</td>
|
|
||||||
<td class="text-right">
|
|
||||||
<button class="btn btn-square btn-ghost btn-xs text-info" @click="openUserModal('edit', user)">
|
|
||||||
<i class="fa fa-edit"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-square btn-ghost btn-xs text-error" @click="deleteUser(user.USERID)">
|
|
||||||
<i class="fa fa-trash"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</template>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
<template x-if="!isLoading && !list.length">
|
|
||||||
<div class="text-center py-10">
|
|
||||||
<i class="fa fa-inbox text-4xl mb-2 opacity-50"></i>
|
|
||||||
<p>No users found</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<!-- User Modal -->
|
|
||||||
<dialog id="user_modal" class="modal">
|
|
||||||
<div class="modal-box p-0 overflow-hidden w-11/12 max-w-lg bg-base-100 shadow-2xl">
|
|
||||||
<div class="p-6 flex flex-col gap-4">
|
|
||||||
<div class="alert alert-info shadow-sm py-2 text-sm" x-show="mode === 'edit'">
|
|
||||||
<i class="fa fa-info-circle"></i> Editing user: <span class="font-bold font-mono" x-text="form.userid"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- User ID & Level -->
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
<div class="form-control w-full">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text font-medium text-base-content/70">User ID</span>
|
|
||||||
</label>
|
|
||||||
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
|
||||||
<i class="fa fa-id-badge text-base-content/40"></i>
|
|
||||||
<input type="text" class="grow font-mono" x-model="form.userid" :disabled="mode === 'edit'" placeholder="e.g. USER001" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control w-full">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text font-medium text-base-content/70">Role / Level</span>
|
|
||||||
</label>
|
|
||||||
<select class="select select-bordered w-full focus:select-primary transition-all" x-model="form.userlevel">
|
|
||||||
<option value="" disabled>Select Level</option>
|
|
||||||
<option value="1">Admin</option>
|
|
||||||
<option value="2">Lab</option>
|
|
||||||
<option value="3">Phlebotomist</option>
|
|
||||||
<option value="4">Customer Service</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider text-xs text-base-content/30 my-0">Security</div>
|
|
||||||
|
|
||||||
<!-- Passwords -->
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
<div class="form-control w-full">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text font-medium text-base-content/70">Password</span>
|
|
||||||
<span class="label-text-alt text-xs opacity-50" x-show="mode === 'edit'">(Optional)</span>
|
|
||||||
</label>
|
|
||||||
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
|
||||||
<i class="fa fa-lock text-base-content/40"></i>
|
|
||||||
<input type="password" class="grow" x-model="form.password" placeholder="••••••" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-control w-full">
|
|
||||||
<label class="label">
|
|
||||||
<span class="label-text font-medium text-base-content/70">Confirm</span>
|
|
||||||
</label>
|
|
||||||
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
|
||||||
<i class="fa fa-lock text-base-content/40"></i>
|
|
||||||
<input type="password" class="grow" x-model="form.password_2" placeholder="••••••" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Error Message -->
|
|
||||||
<div x-show="errorMsg"
|
|
||||||
x-transition:enter="transition ease-out duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 transform scale-95"
|
|
||||||
x-transition:enter-end="opacity-100 transform scale-100"
|
|
||||||
class="alert alert-error text-sm shadow-md">
|
|
||||||
<i class="fa fa-exclamation-triangle"></i>
|
|
||||||
<span x-text="errorMsg"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Actions -->
|
|
||||||
<div class="modal-action bg-base-200/50 p-6 m-0 flex justify-between items-center border-t border-base-200">
|
|
||||||
<button class="btn btn-ghost hover:bg-base-200 text-base-content/70" @click="closeModal()">
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary px-8 shadow-lg shadow-primary/30 min-w-[120px]" @click="saveUser()" :disabled="isLoading">
|
|
||||||
<span x-show="isLoading" class="loading loading-spinner loading-xs"></span>
|
|
||||||
<span x-show="!isLoading" x-text="mode === 'create' ? 'Create User' : 'Save Changes'"></span>
|
|
||||||
<i x-show="!isLoading" class="fa fa-save ml-2"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form method="dialog" class="modal-backdrop">
|
|
||||||
<button @click="closeModal()">close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
</div>
|
|
||||||
<?= $this->endSection(); ?>
|
|
||||||
|
|
||||||
<?= $this->section('script') ?>
|
|
||||||
<script type="module">
|
|
||||||
import Alpine from '<?=base_url("js/app.js");?>';
|
|
||||||
|
|
||||||
document.addEventListener('alpine:init', () => {
|
|
||||||
Alpine.data("users", () => ({
|
|
||||||
list: [],
|
|
||||||
mode: 'create',
|
|
||||||
isLoading: false,
|
|
||||||
errorMsg: '',
|
|
||||||
form: {
|
|
||||||
userid: '',
|
|
||||||
userlevel: '',
|
|
||||||
password: '',
|
|
||||||
password_2: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.fetchUsers();
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchUsers() {
|
|
||||||
this.isLoading = true;
|
|
||||||
fetch(`${BASEURL}/api/users`)
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(data => {
|
|
||||||
this.list = data.data ?? [];
|
|
||||||
}).finally(() => {
|
|
||||||
this.isLoading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getRoleName(level) {
|
|
||||||
const map = { 1: 'Administrator', 2: 'Lab', 3: 'Phlebotomist', 4: 'Customer Service' };
|
|
||||||
return map[level] || 'Unknown (' + level + ')';
|
|
||||||
},
|
|
||||||
|
|
||||||
getRoleClass(level) {
|
|
||||||
const map = { 1: 'badge-primary', 2: 'badge-secondary', 3: 'badge-accent', 4: 'badge-neutral' };
|
|
||||||
return map[level] || 'badge-ghost';
|
|
||||||
},
|
|
||||||
|
|
||||||
openUserModal(targetMode, user = null) {
|
|
||||||
this.mode = targetMode;
|
|
||||||
this.errorMsg = '';
|
|
||||||
|
|
||||||
if (targetMode === 'edit' && user) {
|
|
||||||
this.form = {
|
|
||||||
userid: user.USERID,
|
|
||||||
userlevel: user.USERLEVEL,
|
|
||||||
password: '',
|
|
||||||
password_2: ''
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
this.form = { userid: '', userlevel: '', password: '', password_2: '' };
|
|
||||||
}
|
|
||||||
document.getElementById('user_modal').showModal();
|
|
||||||
},
|
|
||||||
|
|
||||||
closeModal() {
|
|
||||||
document.getElementById('user_modal').close();
|
|
||||||
},
|
|
||||||
|
|
||||||
async saveUser() {
|
|
||||||
this.errorMsg = '';
|
|
||||||
this.isLoading = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
let res;
|
|
||||||
if(this.mode == 'create') {
|
|
||||||
res = await fetch(`${BASEURL}/api/users`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(this.form)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res = await fetch(`${BASEURL}/api/users/${this.form.userid}`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(this.form)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const data = await res.json();
|
|
||||||
if (!res.ok) throw new Error(data.messages?.error || data.message || 'Error saving user');
|
|
||||||
return data;
|
|
||||||
} catch (err) {
|
|
||||||
this.errorMsg = err.message;
|
|
||||||
} finally {
|
|
||||||
this.isLoading = false;
|
|
||||||
this.closeModal();
|
|
||||||
this.fetchUsers();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
Alpine.start();
|
|
||||||
</script>
|
|
||||||
<?= $this->endSection(); ?>
|
|
||||||
@ -28,20 +28,13 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-base-200 min-h-screen" x-data="main">
|
<body class="bg-base-200 min-h-screen" x-data="main">
|
||||||
<div class="drawer">
|
<div class="flex flex-col min-h-screen">
|
||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content flex flex-col min-h-screen">
|
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||||
<div class="flex-none">
|
|
||||||
<label for="main-drawer" aria-label="open sidebar" class="btn btn-square btn-ghost">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class='flex-1'>
|
<div class='flex-1'>
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
||||||
<i class="fa fa-cube"></i> CMOD <span
|
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">|
|
||||||
class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Customer Service Dashboard</span>
|
Customer Service Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -51,8 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-end">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
<span class="text-xl"><i class="fa fa-bars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ul tabindex="0"
|
||||||
|
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-lg border border-base-300">
|
||||||
|
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
||||||
|
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||||
|
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
||||||
|
<div class="divider my-1"></div>
|
||||||
|
<li><a href="<?= base_url('cs') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -64,31 +65,8 @@
|
|||||||
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="drawer-side z-50">
|
|
||||||
<label for="main-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
||||||
<ul class="menu bg-base-100 text-base-content min-h-full w-80 p-4 flex flex-col">
|
|
||||||
<!-- Sidebar content here -->
|
|
||||||
<li class="mb-4">
|
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
|
||||||
<i class="fa fa-cube"></i> CMOD
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="<?= base_url('cs') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<li class="menu-title">Account</li>
|
|
||||||
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
|
||||||
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
|
||||||
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.BASEURL = "<?= base_url("cs"); ?>";
|
window.BASEURL = "<?= base_url(); ?>";
|
||||||
</script>
|
</script>
|
||||||
<?= $this->renderSection('script'); ?>
|
<?= $this->renderSection('script'); ?>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -28,20 +28,13 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-base-200 min-h-screen" x-data="main">
|
<body class="bg-base-200 min-h-screen" x-data="main">
|
||||||
<div class="drawer">
|
<div class="flex flex-col min-h-screen">
|
||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content flex flex-col min-h-screen">
|
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||||
<div class="flex-none">
|
|
||||||
<label for="main-drawer" aria-label="open sidebar" class="btn btn-square btn-ghost">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class='flex-1'>
|
<div class='flex-1'>
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
||||||
<i class="fa fa-cube"></i> CMOD <span
|
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">|
|
||||||
class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Lab Analyst Dashboard</span>
|
Lab Analyst Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -51,8 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-end">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
<span class="text-xl"><i class="fa fa-bars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ul tabindex="0"
|
||||||
|
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-lg border border-base-300">
|
||||||
|
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
||||||
|
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||||
|
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
||||||
|
<div class="divider my-1"></div>
|
||||||
|
<li><a href="<?= base_url('lab') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -64,31 +65,8 @@
|
|||||||
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="drawer-side z-50">
|
|
||||||
<label for="main-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
||||||
<ul class="menu bg-base-100 text-base-content min-h-full w-80 p-4 flex flex-col">
|
|
||||||
<!-- Sidebar content here -->
|
|
||||||
<li class="mb-4">
|
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
|
||||||
<i class="fa fa-cube"></i> CMOD
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="<?= base_url('lab') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<li class="menu-title">Account</li>
|
|
||||||
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
|
||||||
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
|
||||||
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.BASEURL = "<?= base_url("lab"); ?>";
|
window.BASEURL = "<?= base_url(); ?>";
|
||||||
</script>
|
</script>
|
||||||
<?= $this->renderSection('script'); ?>
|
<?= $this->renderSection('script'); ?>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -28,20 +28,13 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-base-200 min-h-screen" x-data="main">
|
<body class="bg-base-200 min-h-screen" x-data="main">
|
||||||
<div class="drawer">
|
<div class="flex flex-col min-h-screen">
|
||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content flex flex-col min-h-screen">
|
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||||
<div class="flex-none">
|
|
||||||
<label for="main-drawer" aria-label="open sidebar" class="btn btn-square btn-ghost">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class='flex-1'>
|
<div class='flex-1'>
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
||||||
<i class="fa fa-cube"></i> CMOD <span
|
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">|
|
||||||
class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Phlebotomist Dashboard</span>
|
Phlebotomist Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -51,8 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-end">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
<span class="text-xl"><i class="fa fa-bars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ul tabindex="0"
|
||||||
|
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-lg border border-base-300">
|
||||||
|
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
||||||
|
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||||
|
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
||||||
|
<div class="divider my-1"></div>
|
||||||
|
<li><a href="<?= base_url('phlebo') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -64,31 +65,8 @@
|
|||||||
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="drawer-side z-50">
|
|
||||||
<label for="main-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
||||||
<ul class="menu bg-base-100 text-base-content min-h-full w-80 p-4 flex flex-col">
|
|
||||||
<!-- Sidebar content here -->
|
|
||||||
<li class="mb-4">
|
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
|
||||||
<i class="fa fa-cube"></i> CMOD
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="<?= base_url('phlebo') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<li class="menu-title">Account</li>
|
|
||||||
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
|
||||||
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
|
||||||
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.BASEURL = "<?= base_url("phlebo"); ?>";
|
window.BASEURL = "<?= base_url(); ?>";
|
||||||
</script>
|
</script>
|
||||||
<?= $this->renderSection('script'); ?>
|
<?= $this->renderSection('script'); ?>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -28,20 +28,13 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-base-200 min-h-screen" x-data="main">
|
<body class="bg-base-200 min-h-screen" x-data="main">
|
||||||
<div class="drawer">
|
<div class="flex flex-col min-h-screen">
|
||||||
<input id="main-drawer" type="checkbox" class="drawer-toggle" />
|
|
||||||
<div class="drawer-content flex flex-col min-h-screen">
|
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||||
<div class="flex-none">
|
|
||||||
<label for="main-drawer" aria-label="open sidebar" class="btn btn-square btn-ghost">
|
|
||||||
<i class="fa fa-bars"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class='flex-1'>
|
<div class='flex-1'>
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2 ml-2'>
|
||||||
<i class="fa fa-cube"></i> CMOD <span
|
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">|
|
||||||
class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Superuser Dashboard</span>
|
Superuser Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
@ -51,8 +44,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown dropdown-end">
|
<div class="dropdown dropdown-end">
|
||||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
<span class="text-xl"><i class="fa fa-bars"></i></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ul tabindex="0"
|
||||||
|
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow-lg border border-base-300">
|
||||||
|
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
||||||
|
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||||
|
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
||||||
|
<div class="divider my-1"></div>
|
||||||
|
<li><a href="<?= base_url('superuser') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
||||||
|
<li><a href="<?= base_url('superuser/users') ?>"><i class="fa fa-users mr-2"></i> Users</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -64,32 +66,8 @@
|
|||||||
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
<footer class='bg-base-100 p-1 mt-auto'>© <?= date('Y'); ?> - 5Panda</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="drawer-side z-50">
|
|
||||||
<label for="main-drawer" aria-label="close sidebar" class="drawer-overlay"></label>
|
|
||||||
<ul class="menu bg-base-100 text-base-content min-h-full w-80 p-4 flex flex-col">
|
|
||||||
<!-- Sidebar content here -->
|
|
||||||
<li class="mb-4">
|
|
||||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
|
||||||
<i class="fa fa-cube"></i> CMOD
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><a href="<?= base_url('superuser') ?>"><i class="fa fa-chart-bar mr-2"></i> Dashboard</a></li>
|
|
||||||
<li><a href="<?= base_url('superuser/users') ?>"><i class="fa fa-users mr-2"></i> Users </a></li>
|
|
||||||
|
|
||||||
<div class="mt-auto">
|
|
||||||
<li class="menu-title">Account</li>
|
|
||||||
<li><a @click.prevent="openDialogSetPassword()"><i class="fa fa-key mr-2"></i> Change Password</a></li>
|
|
||||||
<li><a href="<?= base_url('logout') ?>" class="text-error hover:bg-error/10"><i
|
|
||||||
class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.BASEURL = "<?= base_url("superuser"); ?>";
|
window.BASEURL = "<?= base_url(); ?>";
|
||||||
</script>
|
</script>
|
||||||
<?= $this->renderSection('script'); ?>
|
<?= $this->renderSection('script'); ?>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -19,17 +19,29 @@
|
|||||||
<table class="table table-zebra w-full">
|
<table class="table table-zebra w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th><div class="skeleton h-4 w-24"></div></th>
|
<th>
|
||||||
<th><div class="skeleton h-4 w-24"></div></th>
|
<div class="skeleton h-4 w-24"></div>
|
||||||
<th class="text-right"><div class="skeleton h-4 w-16 ml-auto"></div></th>
|
</th>
|
||||||
|
<th>
|
||||||
|
<div class="skeleton h-4 w-24"></div>
|
||||||
|
</th>
|
||||||
|
<th class="text-right">
|
||||||
|
<div class="skeleton h-4 w-16 ml-auto"></div>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<template x-for="i in 5" :key="i">
|
<template x-for="i in 5" :key="i">
|
||||||
<tr>
|
<tr>
|
||||||
<td><div class="skeleton h-4 w-20"></div></td>
|
<td>
|
||||||
<td><div class="skeleton h-4 w-24"></div></td>
|
<div class="skeleton h-4 w-20"></div>
|
||||||
<td class="text-right"><div class="skeleton h-4 w-16 ml-auto"></div></td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="skeleton h-4 w-24"></div>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="skeleton h-4 w-16 ml-auto"></div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -40,6 +52,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>User ID</th>
|
<th>User ID</th>
|
||||||
|
<th>Username</th>
|
||||||
<th>Role/Level</th>
|
<th>Role/Level</th>
|
||||||
<th class="text-right">Actions</th>
|
<th class="text-right">Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -48,10 +61,10 @@
|
|||||||
<template x-for="user in list" :key="user.USERID">
|
<template x-for="user in list" :key="user.USERID">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font-bold" x-text="user.USERID"></td>
|
<td class="font-bold" x-text="user.USERID"></td>
|
||||||
|
<td class="font-bold" x-text="user.USERNAME"></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="badge"
|
<span class="badge" :class="getRoleClass(user.USERROLEID)"
|
||||||
:class="getRoleClass(user.USERLEVEL)"
|
x-text="getRoleName(user.USERROLEID)"></span>
|
||||||
x-text="getRoleName(user.USERLEVEL)"></span>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<button class="btn btn-square btn-ghost btn-xs text-info" @click="openUserModal('edit', user)">
|
<button class="btn btn-square btn-ghost btn-xs text-info" @click="openUserModal('edit', user)">
|
||||||
@ -93,7 +106,8 @@
|
|||||||
</label>
|
</label>
|
||||||
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
||||||
<i class="fa fa-id-badge text-base-content/40"></i>
|
<i class="fa fa-id-badge text-base-content/40"></i>
|
||||||
<input type="text" class="grow font-mono" x-model="form.userid" :disabled="mode === 'edit'" placeholder="e.g. USER001" />
|
<input type="text" class="grow font-mono" x-model="form.userid" :disabled="mode === 'edit'"
|
||||||
|
placeholder="e.g. USER001" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -101,16 +115,26 @@
|
|||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text font-medium text-base-content/70">Role / Level</span>
|
<span class="label-text font-medium text-base-content/70">Role / Level</span>
|
||||||
</label>
|
</label>
|
||||||
<select class="select select-bordered w-full focus:select-primary transition-all" x-model="form.userlevel">
|
<select class="select select-bordered w-full focus:select-primary transition-all" x-model="form.userroleid">
|
||||||
<option value="" disabled>Select Level</option>
|
<option value="" disabled>Select Level</option>
|
||||||
<option value="1">Admin</option>
|
<?php foreach (ROLE_NAMES as $key => $role): ?>
|
||||||
<option value="2">Lab</option>
|
<option value="<?= $key ?>"><?= $role ?></option>
|
||||||
<option value="3">Phlebotomist</option>
|
<?php endforeach; ?>
|
||||||
<option value="4">Customer Service</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Username -->
|
||||||
|
<div class="form-control w-full">
|
||||||
|
<label class="label">
|
||||||
|
<span class="label-text font-medium text-base-content/70">Username</span>
|
||||||
|
</label>
|
||||||
|
<label class="input input-bordered flex items-center gap-2 focus-within:input-primary transition-all">
|
||||||
|
<i class="fa fa-user text-base-content/40"></i>
|
||||||
|
<input type="text" class="grow font-mono" x-model="form.username" placeholder="e.g. john.doe" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="divider text-xs text-base-content/30 my-0">Security</div>
|
<div class="divider text-xs text-base-content/30 my-0">Security</div>
|
||||||
|
|
||||||
<!-- Passwords -->
|
<!-- Passwords -->
|
||||||
@ -138,11 +162,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Error Message -->
|
<!-- Error Message -->
|
||||||
<div x-show="errorMsg"
|
<div x-show="errorMsg" x-transition:enter="transition ease-out duration-300"
|
||||||
x-transition:enter="transition ease-out duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 transform scale-95"
|
x-transition:enter-start="opacity-0 transform scale-95"
|
||||||
x-transition:enter-end="opacity-100 transform scale-100"
|
x-transition:enter-end="opacity-100 transform scale-100" class="alert alert-error text-sm shadow-md">
|
||||||
class="alert alert-error text-sm shadow-md">
|
|
||||||
<i class="fa fa-exclamation-triangle"></i>
|
<i class="fa fa-exclamation-triangle"></i>
|
||||||
<span x-text="errorMsg"></span>
|
<span x-text="errorMsg"></span>
|
||||||
</div>
|
</div>
|
||||||
@ -153,7 +175,8 @@
|
|||||||
<button class="btn btn-ghost hover:bg-base-200 text-base-content/70" @click="closeModal()">
|
<button class="btn btn-ghost hover:bg-base-200 text-base-content/70" @click="closeModal()">
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary px-8 shadow-lg shadow-primary/30 min-w-[120px]" @click="saveUser()" :disabled="isLoading">
|
<button class="btn btn-primary px-8 shadow-lg shadow-primary/30 min-w-[120px]" @click="saveUser()"
|
||||||
|
:disabled="isLoading">
|
||||||
<span x-show="isLoading" class="loading loading-spinner loading-xs"></span>
|
<span x-show="isLoading" class="loading loading-spinner loading-xs"></span>
|
||||||
<span x-show="!isLoading" x-text="mode === 'create' ? 'Create User' : 'Save Changes'"></span>
|
<span x-show="!isLoading" x-text="mode === 'create' ? 'Create User' : 'Save Changes'"></span>
|
||||||
<i x-show="!isLoading" class="fa fa-save ml-2"></i>
|
<i x-show="!isLoading" class="fa fa-save ml-2"></i>
|
||||||
@ -179,7 +202,8 @@
|
|||||||
errorMsg: '',
|
errorMsg: '',
|
||||||
form: {
|
form: {
|
||||||
userid: '',
|
userid: '',
|
||||||
userlevel: '',
|
username: '',
|
||||||
|
userroleid: '',
|
||||||
password: '',
|
password: '',
|
||||||
password_2: ''
|
password_2: ''
|
||||||
},
|
},
|
||||||
@ -200,7 +224,7 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
getRoleName(level) {
|
getRoleName(level) {
|
||||||
const map = { 1: 'Administrator', 2: 'Lab', 3: 'Phlebotomist', 4: 'Customer Service' };
|
const map = <?= json_encode(ROLE_NAMES) ?>;
|
||||||
return map[level] || 'Unknown (' + level + ')';
|
return map[level] || 'Unknown (' + level + ')';
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -216,12 +240,13 @@
|
|||||||
if (targetMode === 'edit' && user) {
|
if (targetMode === 'edit' && user) {
|
||||||
this.form = {
|
this.form = {
|
||||||
userid: user.USERID,
|
userid: user.USERID,
|
||||||
userlevel: user.USERLEVEL,
|
username: user.USERNAME,
|
||||||
|
userroleid: user.USERROLEID,
|
||||||
password: '',
|
password: '',
|
||||||
password_2: ''
|
password_2: ''
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.form = { userid: '', userlevel: '', password: '', password_2: '' };
|
this.form = { userid: '', username: '', userroleid: '', password: '', password_2: '' };
|
||||||
}
|
}
|
||||||
document.getElementById('user_modal').showModal();
|
document.getElementById('user_modal').showModal();
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user