finish v2
This commit is contained in:
parent
656aef8f7c
commit
315e2ce400
@ -56,6 +56,10 @@ $routes->post('api/request/validate/(:any)', 'Request::val/$1');
|
||||
$routes->delete('api/request/validate/(:any)', 'Request::unval/$1');
|
||||
$routes->get('api/request', 'Request::index');
|
||||
$routes->get('api/sample/(:any)', 'Sample::show/$1');
|
||||
$routes->post('api/sample/collect/(:any)', 'Sample::collect/$1');
|
||||
$routes->delete('api/sample/collect/(:any)', 'Sample::uncollect/$1');
|
||||
$routes->delete('api/sample/receive/(:any)', 'Sample::unreceive/$1');
|
||||
|
||||
|
||||
$routes->get('api/specimen/(:any)', 'Specimen::show/$1');
|
||||
$routes->post('api/specimen/collect/(:any)', 'Specimen::collect/$1');
|
||||
@ -67,7 +71,7 @@ $routes->group('v2', function($routes) {
|
||||
$routes->get('', 'V2::index');
|
||||
$routes->get('login', 'V2::loginPage');
|
||||
$routes->post('login', 'V2::login');
|
||||
$routes->group('Admin/', ['filter' => 'role:1'], function($routes) {
|
||||
$routes->group('admin', ['filter' => 'role:1'], function($routes) {
|
||||
$routes->get('', 'V2\Admin::index');
|
||||
});
|
||||
});
|
||||
|
||||
@ -3,112 +3,121 @@ namespace App\Controllers;
|
||||
use CodeIgniter\API\ResponseTrait;
|
||||
|
||||
class Sample extends BaseController {
|
||||
use ResponseTrait;
|
||||
use ResponseTrait;
|
||||
|
||||
public function show($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
public function show($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
$sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name],
|
||||
case when format(p.BIRTHDATE,'MMdd')=format(spr.COLLECTIONDATE,'MMdd') then DATEDIFF(YEAR,p.BIRTHDATE, spr.COLLECTIONDATE)
|
||||
else FLOOR(DATEDIFF(DAY, p.BIRTHDATE, spr.COLLECTIONDATE) / 365.25) end ,
|
||||
[Gender] = case
|
||||
when p.SEX = 1 then 'M'
|
||||
when p.SEX = 2 then 'F'
|
||||
else ''
|
||||
end, spr.REQDATE, spo.COMMENTTEXT, dmg.DMG_CKTPNO, dmg.DMG_CPLACEOFBIRTH
|
||||
from SP_REQUESTS spr
|
||||
left join PATIENTS p on p.PATID=spr.PATID
|
||||
left join SP_REQUESTS_OCOM spo on spr.SP_ACCESSNUMBER=spo.SP_ACCESSNUMBER
|
||||
left join GDC_CMOD.dbo.TDL_DEMOGRAPHIC dmg on right(dmg.DMG_CPATNUMBER,15)=right(p.PATNUMBER,15)
|
||||
where spr.PATID=p.PATID and spr.SP_ACCESSNUMBER='$accessnumber'";
|
||||
$query = $db->query($sql);
|
||||
$results = $query->getRowArray();
|
||||
$data = [
|
||||
'patnumber' => $results["patnumber"],
|
||||
'age' => $results[""],
|
||||
'patname' => $results['Name'] ?? '',
|
||||
'reqdate' => $results['REQDATE'] ?? '',
|
||||
'gender' => $results['Gender'] ?? '',
|
||||
'placeofbirth' => $results['DMG_CPLACEOFBIRTH'] ?? '',
|
||||
'ktp' => $results['DMG_CKTPNO'] ?? '',
|
||||
'comment' => $results['COMMENTTEXT'] ?? '',
|
||||
'accessnumber' => $accessnumber,
|
||||
$sql = "SELECT right(p.PATNUMBER,16) as [patnumber], ISNULL(p.FIRSTNAME,'') + ' ' + ISNULL(p.NAME,'') as [Name],
|
||||
case when format(p.BIRTHDATE,'MMdd')=format(spr.COLLECTIONDATE,'MMdd') then DATEDIFF(YEAR,p.BIRTHDATE, spr.COLLECTIONDATE)
|
||||
else FLOOR(DATEDIFF(DAY, p.BIRTHDATE, spr.COLLECTIONDATE) / 365.25) end ,
|
||||
[Gender] = case
|
||||
when p.SEX = 1 then 'M'
|
||||
when p.SEX = 2 then 'F'
|
||||
else ''
|
||||
end, spr.REQDATE, spo.COMMENTTEXT, dmg.DMG_CKTPNO, dmg.DMG_CPLACEOFBIRTH
|
||||
from SP_REQUESTS spr
|
||||
left join PATIENTS p on p.PATID=spr.PATID
|
||||
left join SP_REQUESTS_OCOM spo on spr.SP_ACCESSNUMBER=spo.SP_ACCESSNUMBER
|
||||
left join GDC_CMOD.dbo.TDL_DEMOGRAPHIC dmg on right(dmg.DMG_CPATNUMBER,15)=right(p.PATNUMBER,15)
|
||||
where spr.PATID=p.PATID and spr.SP_ACCESSNUMBER='$accessnumber'";
|
||||
$query = $db->query($sql);
|
||||
$results = $query->getRowArray();
|
||||
$data = [
|
||||
'patnumber' => $results["patnumber"],
|
||||
'age' => $results[""],
|
||||
'patname' => $results['Name'] ?? '',
|
||||
'reqdate' => $results['REQDATE'] ?? '',
|
||||
'gender' => $results['Gender'] ?? '',
|
||||
'placeofbirth' => $results['DMG_CPLACEOFBIRTH'] ?? '',
|
||||
'ktp' => $results['DMG_CKTPNO'] ?? '',
|
||||
'comment' => $results['COMMENTTEXT'] ?? '',
|
||||
'accessnumber' => $accessnumber,
|
||||
];
|
||||
|
||||
$samples = [];
|
||||
$sql = "SELECT req.SAMPTYPEID, req.SAMPCODE, req.SHORTTEXT, tu.STATUS, st.TUBESTATUS
|
||||
from GDC_CMOD.dbo.v_sp_reqtube req
|
||||
left join GDC_CMOD.dbo.TUBES tu on req.SP_ACCESSNUMBER=tu.ACCESSNUMBER and req.SAMPCODE=tu.TUBENUMBER
|
||||
left join glendb.dbo.SP_TUBES st on st.SP_ACCESSNUMBER=req.SP_ACCESSNUMBER and req.SAMPCODE=st.SAMPLETYPE
|
||||
where req.SP_ACCESSNUMBER='$accessnumber'";
|
||||
$query = $db->query($sql);
|
||||
$results = $query->getResultArray();
|
||||
foreach ($results as $row) {
|
||||
$samples[] = [
|
||||
'samptypeid' => $row['SAMPTYPEID'] ?? null,
|
||||
'sampcode' => $row['SAMPCODE'] ?? null,
|
||||
'name' => $row['SHORTTEXT'] ?? '',
|
||||
'colstatus' => $row['STATUS'] ?? '',
|
||||
'tubestatus' => $row['TUBESTATUS'] ?? '',
|
||||
];
|
||||
}
|
||||
$data['samples'] = $samples;
|
||||
|
||||
$samples = [];
|
||||
$sql = "SELECT req.SAMPTYPEID, req.SAMPCODE, req.SHORTTEXT, tu.STATUS, st.TUBESTATUS
|
||||
from GDC_CMOD.dbo.v_sp_reqtube req
|
||||
left join GDC_CMOD.dbo.TUBES tu on req.SP_ACCESSNUMBER=tu.ACCESSNUMBER and req.SAMPCODE=tu.TUBENUMBER
|
||||
left join glendb.dbo.SP_TUBES st on st.SP_ACCESSNUMBER=req.SP_ACCESSNUMBER and req.SAMPCODE=st.SAMPLETYPE
|
||||
where req.SP_ACCESSNUMBER='$accessnumber'";
|
||||
$query = $db->query($sql);
|
||||
$results = $query->getResultArray();
|
||||
foreach ($results as $row) {
|
||||
$samples[] = [
|
||||
'samptypeid' => $row['SAMPTYPEID'] ?? null,
|
||||
'sampcode' => $row['SAMPCODE'] ?? null,
|
||||
'name' => $row['SHORTTEXT'] ?? '',
|
||||
'colstatus' => $row['STATUS'] ?? '',
|
||||
'tubestatus' => $row['TUBESTATUS'] ?? '',
|
||||
];
|
||||
}
|
||||
$data['samples'] = $samples;
|
||||
$resp = [ 'data' => $data ];
|
||||
|
||||
$resp = [ 'data' => $data ];
|
||||
return $this->response->setJSON($resp);
|
||||
}
|
||||
|
||||
public function collect($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
$input = $this->request->getJSON(true);
|
||||
$samplenumber = $input['samplenumber'];
|
||||
$userid = $input['userid'];
|
||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='1', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
||||
$db->query($sql);
|
||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||
VALUES ('$accessnumber', '$samplenumber', '$userid', '1', getdate())";
|
||||
$db->query($sql);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
|
||||
}
|
||||
|
||||
return $this->response->setJSON($resp);
|
||||
}
|
||||
|
||||
public function collect($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
$input = $this->request->getJSON(true);
|
||||
$samplenumber = $input['samplenumber'];
|
||||
$status = $input['status'];
|
||||
$userid = $input['userid'];
|
||||
$sql = "if not exists (select * from GDC_CMOD.dbo.TUBES where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber' and STATUS='$status')
|
||||
begin
|
||||
update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='$status', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'
|
||||
end";
|
||||
$db->query($sql);
|
||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||
VALUES ('$accessnumber', '$samplenumber', '$userid', '$status', getdate())";
|
||||
$db->query($sql);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
|
||||
public function uncollect($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
$input = $this->request->getJSON(true);
|
||||
$samplenumber = $input['samplenumber'];
|
||||
$userid = $input['userid'];
|
||||
$sql = "update GDC_CMOD.dbo.TUBES set USERID='$userid',STATUS='0', COLLECTIONDATE=getdate() where ACCESSNUMBER='$accessnumber' and TUBENUMBER='$samplenumber'";
|
||||
$db->query($sql);
|
||||
$sql = "INSERT INTO GDC_CMOD.dbo.AUDIT_TUBES(ACCESSNUMBER, TUBENUMBER, USERID, STATUS, LOGDATE)
|
||||
VALUES ('$accessnumber', '$samplenumber', '$userid', '0', getdate())";
|
||||
$db->query($sql);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
|
||||
}
|
||||
|
||||
public function unreceive($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
$input = $this->request->getJSON(true);
|
||||
$samplenumber = $input['samplenumber'];
|
||||
// update firebird
|
||||
$sql = "select r.EXTERNALORDERNUMBER, dt.TESTCODE, do.HISCODE from glendb.dbo.TESTS t
|
||||
left join glendb.dbo.DICT_TESTS dt on dt.TESTID=t.TESTID
|
||||
left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID
|
||||
left join glendb.dbo.DICT_TEST_SAMPLES dts on dts.TESTID=t.TESTID
|
||||
left join glendb.dbo.DICT_SAMPLES_TYPES ds on ds.SAMPTYPEID=dts.SAMPTYPEID
|
||||
left join GDC_CMOD.dbo.DICT_TESTS_ORDER do on do.TESTCODE=dt.TESTCODE
|
||||
where t.DEPTH=0
|
||||
and r.ACCESSNUMBER='$req' and ds.SAMPCODE='$samplenumber'";
|
||||
$rows = $db->query($sql)->getResultArray();
|
||||
$his_test = '';
|
||||
foreach( $rows as $row ) {
|
||||
$hon = $row['EXTERNALORDERNUMBER'];
|
||||
$testcode = $row['TESTCODE'];
|
||||
$hiscode = $row['HISCODE'];
|
||||
$his_test .= "'$hiscode',";
|
||||
$lis_test .= "'$testcode',";
|
||||
}
|
||||
$his_test = rtrim($his_test,',');
|
||||
$lis_test = rtrim($lis_test,',');
|
||||
$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)";
|
||||
$rs = odbc_exec($conn,$sql);
|
||||
if (!$rs) {exit("Error in Update FB");}
|
||||
|
||||
public function unreceive($accessnumber) {
|
||||
$db = \Config\Database::connect();
|
||||
$input = $this->request->getJSON(true);
|
||||
$samplenumber = $input['samplenumber'];
|
||||
// update firebird
|
||||
$sql = "select r.EXTERNALORDERNUMBER, dt.TESTCODE, do.HISCODE from glendb.dbo.TESTS t
|
||||
left join glendb.dbo.DICT_TESTS dt on dt.TESTID=t.TESTID
|
||||
left join glendb.dbo.REQUESTS r on r.REQUESTID=t.REQUESTID
|
||||
left join glendb.dbo.DICT_TEST_SAMPLES dts on dts.TESTID=t.TESTID
|
||||
left join glendb.dbo.DICT_SAMPLES_TYPES ds on ds.SAMPTYPEID=dts.SAMPTYPEID
|
||||
left join GDC_CMOD.dbo.DICT_TESTS_ORDER do on do.TESTCODE=dt.TESTCODE
|
||||
where t.DEPTH=0
|
||||
and r.ACCESSNUMBER='$req' and ds.SAMPCODE='$samplenumber'";
|
||||
$rows = $db->query($sql)->getResultArray();
|
||||
$his_test = '';
|
||||
foreach( $rows as $row ) {
|
||||
$hon = $row['EXTERNALORDERNUMBER'];
|
||||
$testcode = $row['TESTCODE'];
|
||||
$hiscode = $row['HISCODE'];
|
||||
$his_test .= "'$hiscode',";
|
||||
$lis_test .= "'$testcode',";
|
||||
}
|
||||
$his_test = rtrim($his_test,',');
|
||||
$lis_test = rtrim($lis_test,',');
|
||||
$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)";
|
||||
$rs = odbc_exec($conn,$sql);
|
||||
if (!$rs) {exit("Error in Update FB");}
|
||||
|
||||
$sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' ";
|
||||
$db->query($sql);
|
||||
$sql = "update SP_TESTS set SP_TESTSTATUS=NULL where SP_ACCESSNUMBER='$req' and SP_TESTCODE in ($lis_test)";
|
||||
$db->query($sql);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
|
||||
}
|
||||
$sql = "update SP_TUBES set TUBESTATUS=0 where SP_ACCESSNUMBER='$accessnumber' and SAMPLETYPE='$samplenumber' ";
|
||||
$db->query($sql);
|
||||
$sql = "update SP_TESTS set SP_TESTSTATUS=NULL where SP_ACCESSNUMBER='$req' and SP_TESTCODE in ($lis_test)";
|
||||
$db->query($sql);
|
||||
return $this->respondCreated([ 'status' => 'success', 'message' => 'Data updated successfully', 'data' => "$accessnumber-$samplenumber" ], 201);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,78 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
|
||||
class V2 extends BaseController {
|
||||
/*
|
||||
public function index() {
|
||||
return view("v2/index");
|
||||
}
|
||||
*/
|
||||
public function index() {
|
||||
$session = session();
|
||||
|
||||
if (! $session->get('isLoggedIn')) {
|
||||
return redirect()->to('v2/login');
|
||||
}
|
||||
public function index() {
|
||||
$session = session();
|
||||
|
||||
// Jika sudah login, arahkan sesuai level
|
||||
switch ($session->get('level')) {
|
||||
case 1: return redirect()->to('v2/admin');
|
||||
case 2: return redirect()->to('v2/dokter');
|
||||
case 3: return redirect()->to('v2/analis');
|
||||
case 4: return redirect()->to('v2/cs');
|
||||
default: return redirect()->to('v2/login');
|
||||
}
|
||||
}
|
||||
|
||||
public function loginPage() {
|
||||
return view("v2/login");
|
||||
}
|
||||
if (! $session->get('isLoggedIn')) {
|
||||
return redirect()->to('v2/login');
|
||||
}
|
||||
|
||||
public function login() {
|
||||
helper(['form', 'url']);
|
||||
$session = session();
|
||||
$db = \Config\Database::connect();
|
||||
// Jika sudah login, arahkan sesuai level
|
||||
switch ($session->get('level')) {
|
||||
case 1:
|
||||
return redirect()->to('v2/admin');
|
||||
case 2:
|
||||
return redirect()->to('v2/dokter');
|
||||
case 3:
|
||||
return redirect()->to('v2/analis');
|
||||
case 4:
|
||||
return redirect()->to('v2/cs');
|
||||
default:
|
||||
return redirect()->to('v2/login');
|
||||
}
|
||||
}
|
||||
|
||||
$userid = strtoupper(trim($this->request->getPost('userid')));
|
||||
$password = $this->request->getPost('password');
|
||||
public function loginPage() {
|
||||
return view("v2/login");
|
||||
}
|
||||
|
||||
// Gunakan raw SQL sesuai kolom di tabel kamu
|
||||
$query = $db->query("SELECT * FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]);
|
||||
$user = $query->getRowArray();
|
||||
public function login() {
|
||||
helper(['form', 'url']);
|
||||
$session = session();
|
||||
$db = \Config\Database::connect();
|
||||
|
||||
if ($user && !empty($user['PASSWORD']) && password_verify($password, $user['PASSWORD'])) {
|
||||
$userid = strtoupper(trim($this->request->getPost('userid')));
|
||||
$password = $this->request->getPost('password');
|
||||
|
||||
// Role untuk url
|
||||
switch ((int)$user['USERLEVEL']) {
|
||||
case 1: $role = 'admin'; break;
|
||||
case 2: $role = 'doctor'; break;
|
||||
case 3: $role = 'analyst'; break;
|
||||
case 4: $role = 'cs'; break;
|
||||
default: $role = ''; break;
|
||||
}
|
||||
// Gunakan raw SQL sesuai kolom di tabel kamu
|
||||
$query = $db->query("SELECT * FROM gdc_cmod.dbo.USERS WHERE USERID = ?", [$userid]);
|
||||
$user = $query->getRowArray();
|
||||
|
||||
// Simpan session
|
||||
$session->set([
|
||||
'isLoggedIn' => true,
|
||||
'userid' => (string) $user['USERID'],
|
||||
'userlevel' => (int) $user['USERLEVEL'],
|
||||
'userrole' => (string) $role,
|
||||
]);
|
||||
if ($user && !empty($user['PASSWORD']) && password_verify($password, $user['PASSWORD'])) {
|
||||
|
||||
// Redirect sesuai level dari data didatabase
|
||||
switch ((int)$user['USERLEVEL']) {
|
||||
case 1: return redirect()->to('v2/admin');
|
||||
case 2: return redirect()->to('v2/doctor');
|
||||
case 3: return redirect()->to('v2/analyst');
|
||||
case 4: return redirect()->to('v2/cs');
|
||||
default: return redirect()->to('v2/login');
|
||||
}
|
||||
} else {
|
||||
$session->setFlashdata('error', 'USERID atau PASSWORD salah.');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
||||
// Role untuk url
|
||||
switch ((int)$user['USERLEVEL']) {
|
||||
case 1:
|
||||
$role = 'admin';
|
||||
break;
|
||||
case 2:
|
||||
$role = 'doctor';
|
||||
break;
|
||||
case 3:
|
||||
$role = 'analyst';
|
||||
break;
|
||||
case 4:
|
||||
$role = 'cs';
|
||||
break;
|
||||
default:
|
||||
$role = '';
|
||||
break;
|
||||
}
|
||||
|
||||
// Simpan session
|
||||
$session->set([
|
||||
'isLoggedIn' => true,
|
||||
'userid' => (string) $user['USERID'],
|
||||
'userlevel' => (int) $user['USERLEVEL'],
|
||||
'userrole' => (string) $role,
|
||||
]);
|
||||
|
||||
// Redirect sesuai level dari data didatabase
|
||||
switch ((int)$user['USERLEVEL']) {
|
||||
case 1:
|
||||
return redirect()->to('v2/admin');
|
||||
case 2:
|
||||
return redirect()->to('v2/doctor');
|
||||
case 3:
|
||||
return redirect()->to('v2/analyst');
|
||||
case 4:
|
||||
return redirect()->to('v2/cs');
|
||||
default:
|
||||
return redirect()->to('v2/login');
|
||||
}
|
||||
} else {
|
||||
$session->setFlashdata('error', 'USERID atau PASSWORD salah.');
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
app/Controllers/V2/Admin.php
Normal file
10
app/Controllers/V2/Admin.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace App\Controllers\V2;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
|
||||
class Admin extends BaseController {
|
||||
public function index() {
|
||||
return view('v2/admin/index');
|
||||
}
|
||||
}
|
||||
@ -60,12 +60,21 @@
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-secondary px-2 py-1"><i class="fa-solid fa-print"></i></button>
|
||||
<button class="btn btn-sm btn-success px-2 py-1" @click="collect(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Coll.</h6></button>
|
||||
<button class="btn btn-sm btn-warning px-2 py-1" @click="uncollect(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Un-Coll.</h6></button>
|
||||
<button class="btn btn-sm btn-warning px-2 py-1" @click="unreceive(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Un-Recv.</h6></button>
|
||||
<template x-if="sample.colstatus == 1">
|
||||
<button class="btn btn-sm btn-success px-2 py-1" @click="collect(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Coll.</h6>
|
||||
</button>
|
||||
</template>
|
||||
<template x-if="sample.colstatus == 0">
|
||||
<button class="btn btn-sm btn-warning px-2 py-1" @click="uncollect(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Un-Coll.</h6>
|
||||
</button>
|
||||
</template>
|
||||
<template x-if="sample.tubestatus != 0">
|
||||
<button class="btn btn-sm btn-warning px-2 py-1" @click="unreceive(sample.sampcode, item.accessnumber)">
|
||||
<h6 class="p-0 m-0">Un-Recv.</h6>
|
||||
</button>
|
||||
</template>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@ -25,50 +25,99 @@
|
||||
</head>
|
||||
<body class="bg-base-200 min-h-screen flex flex-col">
|
||||
|
||||
<nav class="navbar bg-secondary shadow-sm text-white">
|
||||
<div class='flex-1 font-bold'>
|
||||
<a class=''>CMOD</a>
|
||||
<nav class="navbar bg-base-100 shadow-md px-6 z-20">
|
||||
<div class='flex-1'>
|
||||
<a class='text-xl text-primary font-bold tracking-wide flex items-center gap-2'>
|
||||
<i class="fa fa-cube"></i> CMOD <span class="text-base-content/40 font-light text-sm hidden sm:inline-block">| Admin Dashboard</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mr-2">
|
||||
<a>Hi, <?=session('userid'); ?></a>
|
||||
</div>
|
||||
<div class="dropdown dropdown-end p-0">
|
||||
<div tabindex="0" role="button" class="btn btn-sm btn-secondary">Menu</div>
|
||||
<ul tabindex="-1" class="dropdown-content menu bg-base-100 rounded-box z-1 w-46 p-2 shadow-sm text-black">
|
||||
<li><a>Item 1</a></li>
|
||||
<li><a>Item 2</a></li>
|
||||
</ul>
|
||||
<div class="flex gap-2">
|
||||
<div class="text-right hidden sm:block leading-tight">
|
||||
<div class="text-sm font-bold opacity-70">Hi, <?=session('userid'); ?></div>
|
||||
<div class="text-xs opacity-50">Administrator</div>
|
||||
</div>
|
||||
<div class="dropdown dropdown-end">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost avatar placeholder px-2">
|
||||
<span class="text-xl"><i class="fa fa-user"></i></span>
|
||||
</div>
|
||||
<ul tabindex="-1" class="dropdown-content menu bg-base-100 rounded-box z-50 w-52 p-2 shadow-xl border border-base-200 mt-2">
|
||||
<li class="menu-title px-4 py-2">Account</li>
|
||||
<li><a class="active:bg-primary"><i class="fa fa-user-circle mr-2"></i> Profile</a></li>
|
||||
<li><a class="active:bg-primary"><i class="fa fa-cog mr-2"></i> Settings</a></li>
|
||||
<li class="divider my-1"></li>
|
||||
<li><a href="<?=base_url('v2/logout')?>" class="text-error hover:bg-error/10"><i class="fa fa-sign-out-alt mr-2"></i> Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="p-4 flex-1 flex flex-col gap-2" x-data="dashboard">
|
||||
<div class="card bg-base-100">
|
||||
<div class="card-body p-3 max-h-full overflow-y-auto">
|
||||
<div class="flex gap-1">
|
||||
<div class="flex-1 font-bold text-lg">Dashboard</div>
|
||||
<div class="flex gap-1">
|
||||
<button @click="filterKey = 'Pend'" :class="filterKey === 'Pend' ? 'btn-active' : ''" class="btn btn-outline btn-sm"><span x-text="counters.Pend"></span> Pending</button>
|
||||
<button @click="filterKey = 'Coll'" :class="filterKey === 'Coll' ? 'btn-active' : ''" class="btn btn-outline btn-sm btn-secondary"><span x-text="counters.Coll"></span> Collected</button>
|
||||
<button @click="filterKey = 'Recv'" :class="filterKey === 'Recv' ? 'btn-active' : ''" class="btn btn-outline btn-sm btn-primary"><span x-text="counters.Recv"></span> Received</button>
|
||||
<button @click="filterKey = 'Inc'" :class="filterKey === 'Inc' ? 'btn-active' : ''" class="btn btn-outline btn-sm btn-warning"><span x-text="counters.Inc"></span> Incomplete</button>
|
||||
<button @click="filterKey = 'Fin'" :class="filterKey === 'Fin' ? 'btn-active' : ''" class="btn btn-outline btn-sm btn-success"><span x-text="counters.Fin"></span> Final</button>
|
||||
<button @click="filterKey = 'Total'" :class="filterKey === 'Total' ? 'btn-active' : ''" class="btn btn-outline btn-sm"><span x-text="counters.Total"></span> Total</button>
|
||||
<button @click="filterKey = 'Validated'" :class="filterKey === 'Validated' ? 'btn-active' : ''" class="btn btn-outline btn-sm btn-info"><span x-text="validatedCount"></span> Val</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-3 mb-2">
|
||||
<div class="flex-1 flex gap-2 items-center">
|
||||
<div>Date</div>
|
||||
<input type="date" class="input input-sm w-39" x-model="filter.date1"/>-
|
||||
<input type="date" class="input input-sm w-39" x-model="filter.date2"/>
|
||||
<button class="btn btn-sm btn-primary" @click='fetchList()'><i class='fa fa-search'></i>Search</button>
|
||||
<button class="btn btn-sm btn-secondary" @click='reset()'><i class='fa fa-refresh'></i>Reset</button>
|
||||
</div>
|
||||
<div class="flex gap-2 items-center">
|
||||
<div>Filter</div>
|
||||
<input type="text" class="input input-sm w-39" x-model="filterTable" />
|
||||
<div class="card bg-base-100 shadow-xl h-full border border-base-200 overflow-hidden">
|
||||
<div class="card-body p-0 h-full flex flex-col">
|
||||
|
||||
<!-- Header & Filters -->
|
||||
<div class="p-4 border-b border-base-200 bg-base-50">
|
||||
<div class="flex flex-col md:flex-row justify-between items-center gap-4 mb-4">
|
||||
<div class="flex-1">
|
||||
<h2 class="text-2xl font-bold flex items-center gap-2 text-base-content">
|
||||
<i class="fa fa-chart-bar text-primary"></i> Requests Overview
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<!-- Status Filters -->
|
||||
<div class="join shadow-sm bg-base-100 rounded-lg">
|
||||
<button @click="filterKey = 'Total'" :class="filterKey === 'Total' ? 'btn-active btn-neutral text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
All <span class="badge badge-sm badge-ghost ml-1" x-text="counters.Total"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Pend'" :class="filterKey === 'Pend' ? 'btn-active btn-neutral text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Pending <span class="badge badge-sm ml-1" x-text="counters.Pend"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Coll'" :class="filterKey === 'Coll' ? 'btn-active btn-warning text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Coll <span class="badge badge-sm badge-warning ml-1" x-text="counters.Coll"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Recv'" :class="filterKey === 'Recv' ? 'btn-active btn-info text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Recv <span class="badge badge-sm badge-info ml-1" x-text="counters.Recv"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Inc'" :class="filterKey === 'Inc' ? 'btn-active btn-error text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Inc <span class="badge badge-sm badge-error ml-1" x-text="counters.Inc"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Fin'" :class="filterKey === 'Fin' ? 'btn-active btn-success text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Fin <span class="badge badge-sm badge-success ml-1" x-text="counters.Fin"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Validated'" :class="filterKey === 'Validated' ? 'btn-active btn-primary text-white' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Val <span class="badge badge-sm badge-primary ml-1" x-text="validatedCount"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search & Date Filter -->
|
||||
<div class="flex flex-col md:flex-row gap-3 items-end bg-base-100 p-3 rounded-lg border border-base-200 shadow-sm">
|
||||
<div class="form-control">
|
||||
<label class="label text-xs font-bold py-1 text-base-content/60">Date Range</label>
|
||||
<div class="join">
|
||||
<input type="date" class="input input-sm input-bordered join-item" x-model="filter.date1"/>
|
||||
<span class="join-item btn btn-sm btn-ghost no-animation bg-base-200 font-normal px-2">-</span>
|
||||
<input type="date" class="input input-sm input-bordered join-item" x-model="filter.date2"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button class="btn btn-sm btn-primary" @click='fetchList()'><i class='fa fa-search'></i> Search</button>
|
||||
<button class="btn btn-sm btn-ghost text-base-content/70" @click='reset()'><i class='fa fa-sync-alt'></i> Reset</button>
|
||||
</div>
|
||||
|
||||
<span class="flex-1"></span>
|
||||
|
||||
<div class="form-control w-full md:w-auto">
|
||||
<div class="relative">
|
||||
<i class="fa fa-filter absolute left-3 top-2.5 text-base-content/30 text-xs"></i>
|
||||
<input type="text" class="input input-sm input-bordered w-full md:w-64 pl-8" placeholder="Type to filter..." x-model="filterTable" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto px-4 pb-4">
|
||||
<template x-if="list.length">
|
||||
<table class="table table-xs table-zebra w-full">
|
||||
<thead class="bg-base-100 sticky top-0 z-10">
|
||||
@ -122,11 +171,12 @@
|
||||
</table>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php echo $this->include('v2/dialog_sample'); ?>
|
||||
<?php echo $this->include('v2/dialog_val'); ?>
|
||||
<?php echo $this->include('v2/dialog_unval'); ?>
|
||||
<?php echo $this->include('v2/admin/dialog_sample'); ?>
|
||||
<?php echo $this->include('v2/admin/dialog_val'); ?>
|
||||
<?php echo $this->include('v2/admin/dialog_unval'); ?>
|
||||
|
||||
</main>
|
||||
|
||||
@ -171,7 +221,7 @@
|
||||
this.filter.date2 = "2025-03-03";
|
||||
//this.filter.date1 = this.today;
|
||||
//this.filter.date2 = this.today;
|
||||
this.fetchList();
|
||||
//this.fetchList();
|
||||
},
|
||||
|
||||
fetchList(){
|
||||
@ -260,6 +310,36 @@
|
||||
});
|
||||
},
|
||||
|
||||
collect(sampcode, accessnumber) {
|
||||
fetch(`${BASEURL}/api/sample/collect/${accessnumber}`, {
|
||||
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({samplenumber: sampcode, userid: '<?= session('userid'); ?>'})
|
||||
})
|
||||
.then(res => res.json()).then(data => {
|
||||
this.fetchItem(accessnumber);
|
||||
});
|
||||
},
|
||||
|
||||
uncollect(sampcode, accessnumber) {
|
||||
fetch(`${BASEURL}/api/sample/collect/${accessnumber}`, {
|
||||
method: 'DELETE', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({samplenumber: sampcode, userid: '<?= session('userid'); ?>'})
|
||||
})
|
||||
.then(res => res.json()).then(data => {
|
||||
this.fetchItem(accessnumber);
|
||||
});
|
||||
},
|
||||
|
||||
unreceive(sampcode, accessnumber) {
|
||||
fetch(`${BASEURL}/api/sample/unreceive/${accessnumber}`, {
|
||||
method: 'POST', headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({samplenumber: sampcode, userid : '<?= session('userid'); ?>'})
|
||||
})
|
||||
.then(res => res.json()).then(data => {
|
||||
this.fetchItem(accessnumber);
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
validate dialog
|
||||
*/
|
||||
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-theme="cupcake">
|
||||
<html lang="en" data-theme="corporate">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@ -9,41 +9,40 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/js/all.min.js"></script>
|
||||
</head>
|
||||
<body class="min-h-screen flex items-center justify-center bg-gradient-to-br from-green-200 via-blue-100 to-yellow-100">
|
||||
<body class="min-h-screen flex items-center justify-center bg-base-200">
|
||||
<div class="w-full max-w-sm mx-auto">
|
||||
<div class="card bg-base-100 shadow-xl border-2 border-primary">
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body items-center text-center">
|
||||
<div class="avatar mb-2">
|
||||
<div class="w-20 rounded-full ring ring-primary ring-offset-base-100 ring-offset-2">
|
||||
<img src="https://api.dicebear.com/7.x/bottts/svg?seed=fun" alt="Fun Avatar" />
|
||||
<div class="mb-4">
|
||||
<div class="w-16 h-16 rounded-full bg-primary/10 flex items-center justify-center mx-auto text-primary">
|
||||
<i class="fa fa-user-shield text-3xl"></i>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="card-title text-2xl font-bold text-primary mb-2">Welcome to CMOD!</h2>
|
||||
<p class="mb-4 text-base text-gray-500">Sign in to continue your adventure 🚀</p>
|
||||
<form method="post" action="<?=base_url('v2/login')?>" class="w-full flex flex-col gap-3">
|
||||
<h2 class="card-title text-2xl font-semibold text-base-content mb-1">CMOD</h2>
|
||||
<p class="mb-6 text-sm text-base-content/70">Sign in to continue</p>
|
||||
<form method="post" action="<?=base_url('v2/login')?>" class="w-full flex flex-col gap-4">
|
||||
<div class="form-control">
|
||||
<label class="input input-bordered flex items-center gap-2 w-full">
|
||||
<i class="fa fa-user text-primary"></i>
|
||||
<input type="text" name="userid" placeholder="UserID" class="grow" required />
|
||||
<label class="input input-bordered flex items-center gap-2 w-full">
|
||||
<i class="fa fa-user text-base-content/50"></i>
|
||||
<input type="text" name="userid" placeholder="User ID" class="grow" required />
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="input input-bordered flex items-center gap-2 w-full">
|
||||
<i class="fa fa-lock text-primary"></i>
|
||||
<label class="input input-bordered flex items-center gap-2 w-full">
|
||||
<i class="fa fa-lock text-base-content/50"></i>
|
||||
<input type="password" name="password" placeholder="Password" class="grow" required />
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-block mt-2 w-full">
|
||||
<i class="fa fa-sign-in-alt mr-2"></i> Login
|
||||
<button type="submit" class="btn btn-primary btn-block mt-2 w-full font-medium">
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
<div class="mt-4">
|
||||
<span class="text-xs text-gray-400">Forgot password?</span>
|
||||
<a href="#" class="link link-primary ml-1">Contact admin</a>
|
||||
<div class="mt-6 text-center">
|
||||
<a href="#" class="link link-hover text-sm text-base-content/60">Forgot password?</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt-4 text-sm text-gray-400">© 2025 - 5Panda</div>
|
||||
<div class="text-center mt-6 text-xs text-base-content/40">© 2025 - 5Panda. All rights reserved.</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user