forked from mahdahar/crm-summit
Update Fitur Instalasi
This commit is contained in:
parent
d7bd75f5a5
commit
8078b32bbd
@ -211,13 +211,13 @@ $routes->group('certificates', function($routes) {
|
||||
|
||||
// Untuk Index Tiap Menu
|
||||
$routes->get('maintenance', 'Certificates::maintenanceIndex'); // OK
|
||||
// $routes->get('installation', 'Certificates::installationIndex'); // OK
|
||||
$routes->get('installation', 'Certificates::installationIndex'); // OK
|
||||
// $routes->get('training', 'Certificates::trainingIndex'); // OK
|
||||
// $routes->get('calibration', 'Certificates::calibrateIndex'); // OK
|
||||
|
||||
// Untuk Get API
|
||||
$routes->get('api/getindexmaintenance', 'Certificates::getDataIndexMaintenance'); // OK
|
||||
// $routes->get('api/getindexinstallation', 'Certificates::getDataIndexInstallation'); // OK
|
||||
$routes->get('api/getindexinstallation', 'Certificates::getDataIndexInstallation'); // OK
|
||||
// $routes->get('api/getindextraining', 'Certificates::getDataIndexTraining'); // OK
|
||||
// $routes->get('api/getindexcalibrate', 'Certificates::getDataIndexCalibrate');
|
||||
|
||||
|
||||
@ -1666,6 +1666,7 @@ class Activities extends Controller {
|
||||
return view('invtrans_index', $data);
|
||||
}
|
||||
|
||||
// Untuk CRUD Sertifikat Maintenance
|
||||
public function createCertificateMaintenance ($actid, $issuedDate, $userid_owner) {
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
@ -1789,4 +1790,6 @@ class Activities extends Controller {
|
||||
|
||||
$certificateModel->where('actid', $actid)->delete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -15,62 +15,54 @@ class Certificates extends BaseController {
|
||||
|
||||
protected array $data;
|
||||
|
||||
// Untuk Sertifikat Instalasi [1]
|
||||
// Untuk Sertifikat Instalasi (BAI) [1]
|
||||
public function installationIndex() { // Index
|
||||
return view('certificate_installation_index');
|
||||
}
|
||||
public function getDataIndexInstallation() { // Untuk API Get Data
|
||||
// $actid = $this->request->getVar('actid'); Siapa Tahu Buat
|
||||
|
||||
$certificates = [
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11914',
|
||||
'certname' => 'Jokoh Calibration Certificate',
|
||||
'productname' => 'Jokoh',
|
||||
'productnumber' => 'SN-2024-001',
|
||||
'issuedate' => '2024-01-15',
|
||||
'expirydate' => '2025-01-15',
|
||||
'vendor' => 'Summit Calibration Lab',
|
||||
'isval' => null
|
||||
],
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
|
||||
'certname' => 'Electrical Safety Test',
|
||||
'productname' => 'GE Healthcare VIVID',
|
||||
'productnumber' => 'GE-VIV-Q992',
|
||||
'issuedate' => '2024-06-12',
|
||||
'expirydate' => '2026-03-01',
|
||||
'vendor' => 'Pramita Medika Service',
|
||||
'isval' => '2026-03-01'
|
||||
],
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
|
||||
'certname' => 'Electrical Safety Test',
|
||||
'productname' => 'GE Healthcare VIVID',
|
||||
'productnumber' => 'GE-VIV-Q992',
|
||||
'issuedate' => '2024-06-12',
|
||||
'expirydate' => '2026-10-01',
|
||||
'vendor' => 'Pramita Medika Service',
|
||||
'isval' => '2026-09-01'
|
||||
],
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11915',
|
||||
'certname' => 'Electrical Safety Test',
|
||||
'productname' => 'GE Healthcare VIVID',
|
||||
'productnumber' => 'GE-VIV-Q992',
|
||||
'issuedate' => '2024-06-12',
|
||||
'expirydate' => '2026-01-01',
|
||||
'vendor' => 'Pramita Medika Service',
|
||||
'isval' => '2026-09-01'
|
||||
],
|
||||
];
|
||||
$userPosId = session()->get('userposid');
|
||||
$userId = session()->get('userid');
|
||||
|
||||
// If no actid, return all certificates
|
||||
if (empty($certificates)) {
|
||||
return $this->response->setJSON(null);
|
||||
$certificateModel = new CertificateModel();
|
||||
|
||||
// 1. Mulai Query Builder
|
||||
$builder = $certificateModel->select('
|
||||
certificates.cert_id,
|
||||
certificates.cert_number,
|
||||
certificates.cert_name,
|
||||
certificates.cert_type,
|
||||
certificates.actid,
|
||||
certificates.issued_date,
|
||||
certificates.expired_date,
|
||||
certificates.status,
|
||||
certificates.user_validation_at,
|
||||
certificates.spv_validation_at,
|
||||
certificates.manager_validation_at,
|
||||
activities.subject as activity_subject,
|
||||
CONCAT(users.firstname, " ", users.lastname) as fullname
|
||||
')
|
||||
->join('activities', 'activities.actid = certificates.actid', 'left')
|
||||
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||
->where('certificates.cert_type', 'BAI');
|
||||
|
||||
// 2. Filter berdasarkan Role
|
||||
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
|
||||
} else if ($userPosId == 2) { // SPV: Melihat data user yang "reportto"-nya adalah ID supervisor ini
|
||||
$builder->where('users.reportto', $userId);
|
||||
} else if ($userPosId == 4) { // TSOIVD: Hanya melihat data milik sendiri
|
||||
$builder->where('certificates.user_id', $userId);
|
||||
} else {// Role lain: Tidak diberi akses
|
||||
return $this->response->setJSON([]);
|
||||
}
|
||||
|
||||
return $this->response->setJSON($certificates);
|
||||
// 3. Eksekusi Query
|
||||
$allData = $builder->findAll();
|
||||
|
||||
if (empty($allData)) {
|
||||
return $this->response->setJSON([]); // Kembalikan array kosong agar frontend tidak error
|
||||
}
|
||||
|
||||
return $this->response->setJSON($allData);
|
||||
}
|
||||
public function createinstallationPreview($certid = null) { // Untuk Preview Sertifikat
|
||||
//Melakukan search data dari database
|
||||
@ -126,7 +118,8 @@ class Certificates extends BaseController {
|
||||
CONCAT(users.firstname, " ", users.lastname) as fullname
|
||||
')
|
||||
->join('activities', 'activities.actid = certificates.actid', 'left')
|
||||
->join('users', 'users.userid = certificates.user_id', 'left');
|
||||
->join('users', 'users.userid = certificates.user_id', 'left')
|
||||
->where('certificates.cert_type', 'MC');;
|
||||
|
||||
// 2. Filter berdasarkan Role
|
||||
if (in_array($userPosId, [1, 3, 5])) { // Manager & IT: Tidak perlu filter tambahan (lihat semua)
|
||||
@ -268,133 +261,133 @@ class Certificates extends BaseController {
|
||||
|
||||
|
||||
// Untuk Sertifikat Training [3]
|
||||
public function trainingIndex() {
|
||||
return view('certificate_training_index');
|
||||
}
|
||||
public function getDataIndexTraining() {
|
||||
// $actid = $this->request->getVar('actid');
|
||||
// public function trainingIndex() {
|
||||
// return view('certificate_training_index');
|
||||
// }
|
||||
// public function getDataIndexTraining() {
|
||||
// // $actid = $this->request->getVar('actid');
|
||||
|
||||
// Sample data - replace with actual database query
|
||||
$certificates = [
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Jokoh Calibration Certificate',
|
||||
'productname' => 'Jokoh',
|
||||
'productnumber' => 'SN-2024-001',
|
||||
'issuedate' => '2024-01-15',
|
||||
'expirydate' => '2025-01-15',
|
||||
'vendor' => 'Summit Calibration Lab',
|
||||
'isval' => null
|
||||
],
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Electrical Safety Test',
|
||||
'productname' => 'GE Healthcare VIVID',
|
||||
'productnumber' => 'GE-VIV-Q992',
|
||||
'issuedate' => '2024-06-12',
|
||||
'expirydate' => '2026-10-01',
|
||||
'vendor' => 'Pramita Medika Service',
|
||||
'isval' => '2026-03-01'
|
||||
]
|
||||
];
|
||||
// // Sample data - replace with actual database query
|
||||
// $certificates = [
|
||||
// [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Jokoh Calibration Certificate',
|
||||
// 'productname' => 'Jokoh',
|
||||
// 'productnumber' => 'SN-2024-001',
|
||||
// 'issuedate' => '2024-01-15',
|
||||
// 'expirydate' => '2025-01-15',
|
||||
// 'vendor' => 'Summit Calibration Lab',
|
||||
// 'isval' => null
|
||||
// ],
|
||||
// [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Electrical Safety Test',
|
||||
// 'productname' => 'GE Healthcare VIVID',
|
||||
// 'productnumber' => 'GE-VIV-Q992',
|
||||
// 'issuedate' => '2024-06-12',
|
||||
// 'expirydate' => '2026-10-01',
|
||||
// 'vendor' => 'Pramita Medika Service',
|
||||
// 'isval' => '2026-03-01'
|
||||
// ]
|
||||
// ];
|
||||
|
||||
// If no actid, return all certificates
|
||||
if (empty($certificates)) {
|
||||
return $this->response->setJSON(null);
|
||||
}
|
||||
// // If no actid, return all certificates
|
||||
// if (empty($certificates)) {
|
||||
// return $this->response->setJSON(null);
|
||||
// }
|
||||
|
||||
return $this->response->setJSON($certificates);
|
||||
}
|
||||
public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat
|
||||
//Melakukan search data dari database
|
||||
// return $this->response->setJSON($certificates);
|
||||
// }
|
||||
// public function createTrainingPreview($certid = null) { // Untuk Preview Sertifikat
|
||||
// //Melakukan search data dari database
|
||||
|
||||
if (!$certid) {
|
||||
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
|
||||
}
|
||||
// if (!$certid) {
|
||||
// return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
|
||||
// }
|
||||
|
||||
// Get certificate data Berdasarkan certid
|
||||
$certificate = [
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Jokoh Calibration Certificate',
|
||||
'productname' => 'Jokoh',
|
||||
'productnumber' => 'SN-2024-001',
|
||||
'issuedate' => '2024-01-15',
|
||||
'expirydate' => '2025-01-15',
|
||||
'vendor' => 'Summit Calibration Lab',
|
||||
'isval' => null
|
||||
];
|
||||
// // Get certificate data Berdasarkan certid
|
||||
// $certificate = [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Jokoh Calibration Certificate',
|
||||
// 'productname' => 'Jokoh',
|
||||
// 'productnumber' => 'SN-2024-001',
|
||||
// 'issuedate' => '2024-01-15',
|
||||
// 'expirydate' => '2025-01-15',
|
||||
// 'vendor' => 'Summit Calibration Lab',
|
||||
// 'isval' => null
|
||||
// ];
|
||||
|
||||
if (empty($certificate)) { // JIka Tidak Ada
|
||||
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
|
||||
}
|
||||
// if (empty($certificate)) { // JIka Tidak Ada
|
||||
// return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
|
||||
// }
|
||||
|
||||
return $this->previewPdf($certificate, 'training'); // Preview PDF
|
||||
}
|
||||
// return $this->previewPdf($certificate, 'training'); // Preview PDF
|
||||
// }
|
||||
|
||||
|
||||
// Untuk Sertifikat Calibrate [4]
|
||||
public function calibrateIndex() {
|
||||
return view('certificate_calibrate_index');
|
||||
}
|
||||
public function getDataIndexCalibrate() {
|
||||
// $actid = $this->request->getVar('actid');
|
||||
// public function calibrateIndex() {
|
||||
// return view('certificate_calibrate_index');
|
||||
// }
|
||||
// public function getDataIndexCalibrate() {
|
||||
// // $actid = $this->request->getVar('actid');
|
||||
|
||||
// Sample data - replace with actual database query
|
||||
$certificates = [
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Jokoh Calibration Certificate',
|
||||
'productname' => 'Jokoh',
|
||||
'productnumber' => 'SN-2024-001',
|
||||
'issuedate' => '2024-01-15',
|
||||
'expirydate' => '2025-01-15',
|
||||
'vendor' => 'Summit Calibration Lab',
|
||||
'isval' => null
|
||||
],
|
||||
[
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Electrical Safety Test',
|
||||
'productname' => 'GE Healthcare VIVID',
|
||||
'productnumber' => 'GE-VIV-Q992',
|
||||
'issuedate' => '2024-06-12',
|
||||
'expirydate' => '2026-10-01',
|
||||
'vendor' => 'Pramita Medika Service',
|
||||
'isval' => '2026-03-01'
|
||||
]
|
||||
];
|
||||
// // Sample data - replace with actual database query
|
||||
// $certificates = [
|
||||
// [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Jokoh Calibration Certificate',
|
||||
// 'productname' => 'Jokoh',
|
||||
// 'productnumber' => 'SN-2024-001',
|
||||
// 'issuedate' => '2024-01-15',
|
||||
// 'expirydate' => '2025-01-15',
|
||||
// 'vendor' => 'Summit Calibration Lab',
|
||||
// 'isval' => null
|
||||
// ],
|
||||
// [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Electrical Safety Test',
|
||||
// 'productname' => 'GE Healthcare VIVID',
|
||||
// 'productnumber' => 'GE-VIV-Q992',
|
||||
// 'issuedate' => '2024-06-12',
|
||||
// 'expirydate' => '2026-10-01',
|
||||
// 'vendor' => 'Pramita Medika Service',
|
||||
// 'isval' => '2026-03-01'
|
||||
// ]
|
||||
// ];
|
||||
|
||||
// If no actid, return all certificates
|
||||
if (empty($certificates)) {
|
||||
return $this->response->setJSON(null);
|
||||
}
|
||||
// // If no actid, return all certificates
|
||||
// if (empty($certificates)) {
|
||||
// return $this->response->setJSON(null);
|
||||
// }
|
||||
|
||||
return $this->response->setJSON($certificates);
|
||||
}
|
||||
public function createCalibratePreview($certid = null) { // Untuk Preview Sertifikat
|
||||
//Melakukan search data dari database
|
||||
// return $this->response->setJSON($certificates);
|
||||
// }
|
||||
// public function createCalibratePreview($certid = null) { // Untuk Preview Sertifikat
|
||||
// //Melakukan search data dari database
|
||||
|
||||
if (!$certid) {
|
||||
return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
|
||||
}
|
||||
// if (!$certid) {
|
||||
// return $this->response->setStatusCode(400)->setJSON(['error' => 'Certificate ID is required']);
|
||||
// }
|
||||
|
||||
// Get certificate data Berdasarkan certid
|
||||
$certificate = [
|
||||
'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
'certname' => 'Jokoh Calibration Certificate',
|
||||
'productname' => 'Jokoh',
|
||||
'productnumber' => 'SN-2024-001',
|
||||
'issuedate' => '2024-01-15',
|
||||
'expirydate' => '2025-01-15',
|
||||
'vendor' => 'Summit Calibration Lab',
|
||||
'isval' => null
|
||||
];
|
||||
// // Get certificate data Berdasarkan certid
|
||||
// $certificate = [
|
||||
// 'certid' => 'f353ca91-4fc5-49f2-9b9e-304f83d11919',
|
||||
// 'certname' => 'Jokoh Calibration Certificate',
|
||||
// 'productname' => 'Jokoh',
|
||||
// 'productnumber' => 'SN-2024-001',
|
||||
// 'issuedate' => '2024-01-15',
|
||||
// 'expirydate' => '2025-01-15',
|
||||
// 'vendor' => 'Summit Calibration Lab',
|
||||
// 'isval' => null
|
||||
// ];
|
||||
|
||||
if (empty($certificate)) { // JIka Tidak Ada
|
||||
return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
|
||||
}
|
||||
// if (empty($certificate)) { // JIka Tidak Ada
|
||||
// return $this->response->setStatusCode(404)->setJSON(['error' => 'Maintenance certificate not found']);
|
||||
// }
|
||||
|
||||
return $this->previewPdf($certificate, 'calibrate', 'tms24i'); // Preview PDF
|
||||
}
|
||||
// return $this->previewPdf($certificate, 'calibrate', 'tms24i'); // Preview PDF
|
||||
// }
|
||||
|
||||
|
||||
// Helper Function Preview dan Validate
|
||||
|
||||
@ -223,7 +223,7 @@ if(isset($data)) {
|
||||
Calibration Certificate
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="col-md-6 mb-2">
|
||||
<div class="form-check">
|
||||
@ -232,7 +232,7 @@ if(isset($data)) {
|
||||
Installation Certificate
|
||||
</label>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 mb-2">
|
||||
<div class="form-check">
|
||||
@ -250,9 +250,9 @@ if(isset($data)) {
|
||||
Berita Acara Instalasi
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="col-md-6 mb-2">
|
||||
<!-- <div class="col-md-6 mb-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="training" value="1" id="training" <?= in_array('UTC', $cert_types) ? 'checked' : '' ?>>
|
||||
<label class="form-check-label" for="training">
|
||||
@ -637,10 +637,11 @@ if(isset($data)) {
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="form-group">
|
||||
<label for="trainingname" class="form-label">Nama</label>
|
||||
<input type='text' class="form-control form-control-sm trainingname" placeholder="Masukkan nama" />
|
||||
</div>
|
||||
<label for="site" class="form-label border-start border-5 border-primary ps-1">Nama</label>
|
||||
<select name="siteid" id="siteid" class="form-select form-select-sm select2 site" required>
|
||||
<option value="">-- Choose one --</option>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-5">
|
||||
<div class="form-group">
|
||||
@ -988,9 +989,9 @@ $('#status').change(function() {
|
||||
// else { $("#maintenance").prop('disabled', true); $("#calibration").prop('disabled', true); $("#installation").prop('disabled', true); $("#offreport").prop('disabled', true); $("#training").prop('disabled', true);}
|
||||
// })
|
||||
$('#acttypeid').change(function() {
|
||||
if (this.value=='5'){ $("#maintenance").prop('disabled', false); }
|
||||
else if (this.value=='3'){ $("#maintenance").prop('disabled', true);}
|
||||
else { $("#maintenance").prop('disabled', true);}
|
||||
if (this.value=='5'){ $("#maintenance").prop('disabled', false); $("#installation").prop('disabled', true);}
|
||||
else if (this.value=='3'){ $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', false);}
|
||||
else { $("#maintenance").prop('disabled', true); $("#installation").prop('disabled', true);}
|
||||
})
|
||||
|
||||
|
||||
|
||||
@ -1,577 +0,0 @@
|
||||
<?= $this->extend('layouts/main.php') ?>
|
||||
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row page-titles">
|
||||
<div class="col-md-5 align-self-center">
|
||||
<h4 class="text-themecolor">Certificates Management</h4>
|
||||
</div>
|
||||
<!-- <div class="col-md-7 align-self-center text-end">
|
||||
<button type="button" class="btn btn-info text-white btn-sm" data-bs-toggle="modal" data-bs-target="#createModal">
|
||||
<i class="fas fa-plus-circle"></i> Create
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="Search certificates by name, product, type, vendor, or dates...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="statusFilter" class="form-select form-select-sm">
|
||||
<option value="">All Status</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="expired">Expired</option>
|
||||
<option value="expiring">Expiring Soon</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="typeFilter" class="form-select form-select-sm">
|
||||
<option value="">All Types</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
||||
<i class="fas fa-redo"></i> Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="certificatesTable" class="table table-striped table-hover border">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th class="text-center" style="width: 5%;">No</th>
|
||||
<th style="width: 15%;">Certificate Name</th>
|
||||
<th style="width: 15%;">Product/Equipment</th>
|
||||
<th style="width: 12%;">Type</th>
|
||||
<th style="width: 12%;">Issue Date</th>
|
||||
<th style="width: 12%;">Expiry Date</th>
|
||||
<th style="width: 10%;">Status</th>
|
||||
<th style="width: 10%;">Vendor</th>
|
||||
<th class="text-center" style="width: 9%;">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if(isset($certificates) && !empty($certificates)) {
|
||||
$no = 1;
|
||||
foreach($certificates as $cert) {
|
||||
$certid = $cert['certid'] ?? '';
|
||||
$certname = $cert['certname'] ?? '-';
|
||||
$productname = $cert['productname'] ?? '-';
|
||||
$productnumber = $cert['productnumber'] ?? '';
|
||||
$type = $cert['type'] ?? '-';
|
||||
$issuedate = $cert['issuedate'] ?? '';
|
||||
$expirydate = $cert['expirydate'] ?? '';
|
||||
$vendor = $cert['vendor'] ?? '-';
|
||||
|
||||
// Format dates
|
||||
if($issuedate && $issuedate != '0000-00-00') {
|
||||
$issuedate = date('M d, Y', strtotime($issuedate));
|
||||
} else {
|
||||
$issuedate = '-';
|
||||
}
|
||||
|
||||
if($expirydate && $expirydate != '0000-00-00') {
|
||||
$expirydate = date('M d, Y', strtotime($expirydate));
|
||||
// Check expiry status
|
||||
$today = date('Y-m-d');
|
||||
$expiryCheck = date('Y-m-d', strtotime($cert['expirydate']));
|
||||
$daysUntilExpiry = (strtotime($expiryCheck) - strtotime($today)) / (60 * 60 * 24);
|
||||
|
||||
if($daysUntilExpiry < 0) {
|
||||
$statusBadge = '<span class="badge bg-danger">Expired</span>';
|
||||
$statusClass = 'expired';
|
||||
} elseif($daysUntilExpiry <= 30) {
|
||||
$statusBadge = '<span class="badge bg-warning text-dark">Expiring Soon</span>';
|
||||
$statusClass = 'expiring';
|
||||
} else {
|
||||
$statusBadge = '<span class="badge bg-success">Active</span>';
|
||||
$statusClass = 'active';
|
||||
}
|
||||
} else {
|
||||
$expirydate = '-';
|
||||
$statusBadge = '<span class="badge bg-secondary">N/A</span>';
|
||||
$statusClass = '';
|
||||
}
|
||||
|
||||
// Type badge
|
||||
$typeBadge = '';
|
||||
switch(strtolower($type)) {
|
||||
case 'calibration':
|
||||
$typeBadge = '<span class="badge bg-info">Calibration</span>';
|
||||
break;
|
||||
case 'training':
|
||||
$typeBadge = '<span class="badge bg-primary">Training</span>';
|
||||
break;
|
||||
case 'maintenance':
|
||||
$typeBadge = '<span class="badge bg-warning text-dark">Maintenance</span>';
|
||||
break;
|
||||
default:
|
||||
$typeBadge = '<span class="badge bg-secondary">' . htmlspecialchars($type) . '</span>';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-center"><?= $no++; ?></td>
|
||||
<td>
|
||||
<strong><?= htmlspecialchars($certname) ?></strong>
|
||||
<br>
|
||||
<small class="text-muted">ID: <?= $certid ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<?= htmlspecialchars($productname) ?>
|
||||
<?php if($productnumber): ?>
|
||||
<br><small class="text-muted">SN: <?= htmlspecialchars($productnumber) ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= $typeBadge ?></td>
|
||||
<td><?= $issuedate ?></td>
|
||||
<td><?= $expirydate ?></td>
|
||||
<td><?= $statusBadge ?></td>
|
||||
<td><?= htmlspecialchars($vendor) ?></td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-success btn-view" data-certid="<?= $certid ?>" data-certtype="<?= $type ?>" title="View PDF">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</button>
|
||||
<!-- <button type="button" class="btn btn-warning btn-edit" data-certid="<?= $certid ?>" title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger btn-delete" data-certid="<?= $certid ?>" data-certname="<?= htmlspecialchars($certname) ?>" title="Delete">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button> -->
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<!-- <tr>
|
||||
<td colspan="9" class="text-center py-5">
|
||||
<i class="fas fa-certificate fa-3x text-muted mb-3"></i>
|
||||
<p class="text-muted">No certificates found</p>
|
||||
<button type="button" class="btn btn-info text-white btn-sm" data-bs-toggle="modal" data-bs-target="#createModal">
|
||||
<i class="fas fa-plus-circle"></i> Add First Certificate
|
||||
</button>
|
||||
</td>
|
||||
</tr> -->
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Modal -->
|
||||
<!-- <div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-info text-white">
|
||||
<h5 class="modal-title" id="createModalLabel">
|
||||
<i class="fas fa-plus-circle"></i> Create New Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form id="createForm" action="<?= base_url('certificates/create') ?>" method="post">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="certname" class="form-label">Certificate Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="certname" name="certname" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="type" class="form-label">Type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="type" name="type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="productid" class="form-label">Product/Equipment</label>
|
||||
<select class="form-select select2" id="productid" name="productid">
|
||||
<option value="">Select Product</option>
|
||||
<?php if(isset($products)): ?>
|
||||
<?php foreach($products as $product): ?>
|
||||
<option value="<?= $product['productid'] ?>">
|
||||
<?= htmlspecialchars($product['productname']) ?>
|
||||
<?php if($product['productnumber']): ?>
|
||||
(SN: <?= htmlspecialchars($product['productnumber']) ?>)
|
||||
<?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="vendor" class="form-label">Vendor/Provider</label>
|
||||
<input type="text" class="form-control" id="vendor" name="vendor">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="issuedate" class="form-label">Issue Date</label>
|
||||
<input type="date" class="form-control" id="issuedate" name="issuedate">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="expirydate" class="form-label">Expiry Date</label>
|
||||
<input type="date" class="form-control" id="expirydate" name="expirydate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="attachment" class="form-label">Attachment</label>
|
||||
<input type="file" class="form-control" id="attachment" name="attachment" accept=".pdf,.jpg,.jpeg,.png">
|
||||
<small class="text-muted">Allowed: PDF, JPG, PNG (Max 5MB)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-info text-white">
|
||||
<i class="fas fa-save"></i> Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<!-- <div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-warning text-dark">
|
||||
<h5 class="modal-title" id="editModalLabel">
|
||||
<i class="fas fa-edit"></i> Edit Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form id="editForm" action="<?= base_url('certificates/update') ?>" method="post">
|
||||
<input type="hidden" id="edit_certid" name="certid">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_certname" class="form-label">Certificate Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="edit_certname" name="certname" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_type" class="form-label">Type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="edit_type" name="type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_productid" class="form-label">Product/Equipment</label>
|
||||
<select class="form-select select2" id="edit_productid" name="productid">
|
||||
<option value="">Select Product</option>
|
||||
<?php if(isset($products)): ?>
|
||||
<?php foreach($products as $product): ?>
|
||||
<option value="<?= $product['productid'] ?>">
|
||||
<?= htmlspecialchars($product['productname']) ?>
|
||||
<?php if($product['productnumber']): ?>
|
||||
(SN: <?= htmlspecialchars($product['productnumber']) ?>)
|
||||
<?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_vendor" class="form-label">Vendor/Provider</label>
|
||||
<input type="text" class="form-control" id="edit_vendor" name="vendor">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_issuedate" class="form-label">Issue Date</label>
|
||||
<input type="date" class="form-control" id="edit_issuedate" name="issuedate">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_expirydate" class="form-label">Expiry Date</label>
|
||||
<input type="date" class="form-control" id="edit_expirydate" name="expirydate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="edit_description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="edit_description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-warning text-dark">
|
||||
<i class="fas fa-save"></i> Update
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- View Modal -->
|
||||
<!-- <div class="modal fade" id="viewModal" tabindex="-1" aria-labelledby="viewModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-success text-white">
|
||||
<h5 class="modal-title" id="viewModalLabel">
|
||||
<i class="fas fa-eye"></i> Certificate Details
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="viewContent">
|
||||
Content loaded via AJAX
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Close
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="btnPrint">
|
||||
<i class="fas fa-print"></i> Print
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<!-- <div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title" id="deleteModalLabel">
|
||||
<i class="fas fa-exclamation-triangle"></i> Confirm Delete
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete this certificate?</p>
|
||||
<div class="alert alert-warning">
|
||||
<strong>Certificate:</strong> <span id="deleteCertName"></span>
|
||||
</div>
|
||||
<p class="text-muted small">This action cannot be undone.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<form id="deleteForm" action="<?= base_url('certificates/delete') ?>" method="post">
|
||||
<input type="hidden" id="delete_certid" name="certid">
|
||||
<button type="submit" class="btn btn-danger text-white">
|
||||
<i class="fas fa-trash"></i> Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('script') ?>
|
||||
<script>
|
||||
$(function () {
|
||||
// Store DataTable instance
|
||||
var table = null;
|
||||
|
||||
// Initialize DataTable
|
||||
table = $('#certificatesTable').DataTable({
|
||||
"order": [[0, "asc"]],
|
||||
"pageLength": 25,
|
||||
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
|
||||
"language": {
|
||||
"emptyTable": "No certificates available",
|
||||
"info": "Showing _START_ to _END_ of _TOTAL_ certificates",
|
||||
"infoEmpty": "No certificates found",
|
||||
"infoFiltered": "(filtered from _MAX_ total certificates)"
|
||||
},
|
||||
"dom": '<"row"<"col-md-6"l>>rtip',
|
||||
"columnDefs": [
|
||||
{ "orderable": false, "targets": [8] }, // Disable sorting on Action column
|
||||
{ "searchable": true, "targets": [0, 1, 2, 3, 4, 5, 6, 7] } // Enable search on all columns except Action
|
||||
]
|
||||
});
|
||||
|
||||
// Hide default DataTables search
|
||||
$('#certificatesTable_filter').hide();
|
||||
|
||||
// Initialize Select2
|
||||
$('.select2').select2({
|
||||
theme: 'bootstrap-5',
|
||||
width: '100%',
|
||||
dropdownParent: $('.modal')
|
||||
});
|
||||
|
||||
// Custom search functionality
|
||||
$('#searchInput').on('keyup', function() {
|
||||
var searchValue = $(this).val().toLowerCase();
|
||||
table.search(searchValue).draw();
|
||||
});
|
||||
|
||||
// Status filter using DataTables column filter
|
||||
$('#statusFilter').on('change', function() {
|
||||
var status = $(this).val();
|
||||
|
||||
// Filter by status column (index 6)
|
||||
if(status === '') {
|
||||
table.column(6).search('').draw();
|
||||
} else {
|
||||
// Search for the badge text in status column
|
||||
var statusText = '';
|
||||
switch(status) {
|
||||
case 'active':
|
||||
statusText = 'Active';
|
||||
break;
|
||||
case 'expired':
|
||||
statusText = 'Expired';
|
||||
break;
|
||||
case 'expiring':
|
||||
statusText = 'Expiring Soon';
|
||||
break;
|
||||
}
|
||||
table.column(6).search(statusText).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Type filter using DataTables column filter
|
||||
$('#typeFilter').on('change', function() {
|
||||
var type = $(this).val();
|
||||
|
||||
// Filter by type column (index 3)
|
||||
if(type === '') {
|
||||
table.column(3).search('').draw();
|
||||
} else {
|
||||
// Capitalize first letter for search
|
||||
var typeText = type.charAt(0).toUpperCase() + type.slice(1);
|
||||
table.column(3).search(typeText).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Reset filters
|
||||
window.resetFilters = function() {
|
||||
$('#searchInput').val('');
|
||||
$('#statusFilter').val('');
|
||||
$('#typeFilter').val('');
|
||||
|
||||
// Reset DataTables search and filters
|
||||
table.search('').columns().search('').draw();
|
||||
|
||||
// Re-apply default ordering
|
||||
table.order([5, 'asc']).draw();
|
||||
};
|
||||
|
||||
// View button click - Open PDF in new tab based on certificate type
|
||||
$(document).on('click', '.btn-view', function() {
|
||||
var certid = $(this).data('certid');
|
||||
var certType = $(this).data('certtype');
|
||||
|
||||
var url = '';
|
||||
switch(certType) {
|
||||
case 'training':
|
||||
url = '<?= base_url('certificates/training/show') ?>/' + certid;
|
||||
break;
|
||||
case 'calibration':
|
||||
url = '<?= base_url('certificates/calibrate/show') ?>/' + certid;
|
||||
break;
|
||||
case 'maintenance':
|
||||
url = '<?= base_url('certificates/maintenance/show') ?>/' + certid;
|
||||
break;
|
||||
default:
|
||||
url = '<?= base_url('certificates/view') ?>/' + certid;
|
||||
}
|
||||
|
||||
window.open(url, '_blank');
|
||||
});
|
||||
|
||||
// Edit button click
|
||||
// $(document).on('click', '.btn-edit', function() {
|
||||
// var certid = $(this).data('certid');
|
||||
// $('#edit_certid').val(certid);
|
||||
// $('#editModal').modal('show');
|
||||
|
||||
// // Load certificate data via AJAX
|
||||
// $.get('<?= base_url('certificates/get') ?>/' + certid, function(data) {
|
||||
// $('#edit_certname').val(data.certname);
|
||||
// $('#edit_type').val(data.type);
|
||||
// $('#edit_productid').val(data.productid).trigger('change');
|
||||
// $('#edit_vendor').val(data.vendor);
|
||||
// $('#edit_issuedate').val(data.issuedate);
|
||||
// $('#edit_expirydate').val(data.expirydate);
|
||||
// $('#edit_description').val(data.description);
|
||||
// }).fail(function() {
|
||||
// $('#editModal').modal('hide');
|
||||
// alert('Failed to load certificate data.');
|
||||
// });
|
||||
// });
|
||||
|
||||
// Delete button click
|
||||
// $(document).on('click', '.btn-delete', function() {
|
||||
// var certid = $(this).data('certid');
|
||||
// var certname = $(this).data('certname');
|
||||
// $('#delete_certid').val(certid);
|
||||
// $('#deleteCertName').text(certname);
|
||||
// $('#deleteModal').modal('show');
|
||||
// });
|
||||
|
||||
// Print button
|
||||
$('#btnPrint').on('click', function() {
|
||||
window.print();
|
||||
});
|
||||
|
||||
// Form validation
|
||||
// $('#createForm, #editForm').on('submit', function(e) {
|
||||
// var form = this;
|
||||
// if(form.checkValidity()) {
|
||||
// // Form is valid, submit
|
||||
// return true;
|
||||
// }
|
||||
// e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
// form.classList.add('was-validated');
|
||||
// });
|
||||
|
||||
// Date picker enhancement
|
||||
$('input[type="date"]').on('focus', function() {
|
||||
this.showPicker();
|
||||
});
|
||||
|
||||
// Re-attach event handlers after DataTables pagination/draw
|
||||
table.on('draw.dt', function() {
|
||||
// Event handlers are already attached using $(document).on(), so no need to re-attach
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
@ -3,167 +3,162 @@
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row page-titles">
|
||||
<div class="col-md-5 align-self-center">
|
||||
<h4 class="text-themecolor">Certificates Installation Management</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row page-titles">
|
||||
<div class="col-md-5 align-self-center">
|
||||
<h4 class="text-themecolor">Certificates Installation Management</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
<input type="text" id="searchInput" class="form-control"
|
||||
placeholder="Search certificates by name, product, type, vendor, or dates...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="statusFilter" class="form-select form-select-sm">
|
||||
<option value="">All Status</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="expired">Expired</option>
|
||||
<option value="expiring">Expiring Soon</option>
|
||||
<option value="isval">Need Validation</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="typeFilter" class="form-select form-select-sm">
|
||||
<option value="">All Types</option>
|
||||
<option value="tms">TMS</option>
|
||||
<option value="joko">Jokoh</option>
|
||||
<option value="boeki">Tokyo Boeki</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
||||
<i class="fas fa-redo"></i> Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
<input type="text" id="searchInput" class="form-control"
|
||||
placeholder="Search certificates by name, product, type, vendor, or dates...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="productFilter" class="form-select form-select-sm">
|
||||
<option value="">--Product Filter--</option>
|
||||
<option value="tms">TMS</option>
|
||||
<option value="jokoh">Jokoh</option>
|
||||
<option value="mindray">Mindray</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="validationFilter" class="form-select form-select-sm">
|
||||
<option value="">--Validation Filter--</option>
|
||||
<option value="valid">Validated</option>
|
||||
<option value="unval">Unvalidated</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
||||
<i class="fas fa-redo"></i> Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TABLE -->
|
||||
<div class="table-responsive" style="width: 100%;">
|
||||
<table id="certificatesTable" class="table table-striped table-hover border" style="width: 100%;">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th style="width:20%">Certificate Name</th>
|
||||
<th style="width:20%">Product/Equipment</th>
|
||||
<th style="width:20%">Activity Report</th>
|
||||
<th style="width:10%">Issue Date</th>
|
||||
<th style="width:10%">Expiry Date</th>
|
||||
<th style="width:10%">Status</th>
|
||||
<th class="text-center" style="width:10%">Action</th>
|
||||
<th style="width: 32%">Certificate</th>
|
||||
<th style="width: 38%">Act Report</th>
|
||||
<th style="width: 10%">Issue Date</th>
|
||||
<th style="width: 8%">Validation</th>
|
||||
<th class="text-center" style="width: 12%">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Validate Modal -->
|
||||
<div class="modal fade" id="validateModal" tabindex="-1" aria-labelledby="validateModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-warning text-dark">
|
||||
<h5 class="modal-title" id="validateModalLabel">
|
||||
<i class="fa-solid fa-check-double"></i> Validate Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Certificate ID</label>
|
||||
<p id="modalCertId" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Certificate Name</label>
|
||||
<p id="modalCertName" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Product/Equipment</label>
|
||||
<p id="modalProductName" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Serial Number</label>
|
||||
<p id="modalProductNumber" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Issue Date</label>
|
||||
<p id="modalIssueDate" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Expiry Date</label>
|
||||
<p id="modalExpiryDate" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Vendor</label>
|
||||
<p id="modalVendor" class="form-control-plaintext">-</p>
|
||||
</div>
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-warning text-dark" id='modalHeader'>
|
||||
<h5 class="modal-title" id="validateModalLabel">
|
||||
Validate installation Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row border-bottom mb-3 pb-2">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label "><i class="fa-solid fa-certificate me-2"></i>Certificate Name</label>
|
||||
<h5 id="modalCertName" class="mt-2 fw-bolder">-</h5>
|
||||
</div>
|
||||
<div class="col-md-4 text-md-end">
|
||||
<h5 id="modalValidation">-</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label fw-bold">Activity Report</label>
|
||||
<p id="modalExpiryDate" class="form-control-plaintext">
|
||||
<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" style="color:#d43215b0;">Act ID - Nama AR - Nama User <i class="fa-solid fa-up-right-from-square"></i></a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fa-solid fa-info-circle"></i>
|
||||
<strong>Validation Information:</strong> Please review the certificate details above before validating. Once validated, the certificate status will change from "Need Validation" to "Active".
|
||||
</div>
|
||||
<label class="form-label "><i class="fa-solid fa-book-medical me-2"></i>Certificate Number</label>
|
||||
<p id="modalCertNumber" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label "><i class="fa-solid fa-microchip me-2"></i>Product/Equipment</label>
|
||||
<p id="modalProductName" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label "><i class="fa-solid fa-hashtag me-2"></i>Serial Number</label>
|
||||
<p id="modalProductNumber" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label "><i class="fa-regular fa-hospital me-2"></i>Site</label>
|
||||
<p id="modalSiteName" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-12 mb-3">
|
||||
<label class="form-label "><i class="fa-solid fa-calendar-check me-2"></i>Issue Date</label>
|
||||
<p id="modalIssueDate" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-3">
|
||||
<label class="form-label fw-bold">Certificate Preview</label>
|
||||
<div class="border rounded p-2" style="height: 500px; overflow: hidden;">
|
||||
<iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 mb-4">
|
||||
<label class="form-label "><i class="fa-solid fa-file-lines me-2"></i>Activity Report Reference</label>
|
||||
<a href="javascript:void(0)" id="modalActivityLink" class="activity-report-link text-decoration-none fw-bolder" style="color:#d43215b0;">
|
||||
<div class="p-2 border rounded bg-light">
|
||||
<i class="fa-solid fa-up-right-from-square me-2"></i>
|
||||
<span id="modalActivity">-</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fa-solid fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning text-dark" id="confirmValidateBtn">
|
||||
<i class="fa-solid fa-check"></i> Validate Certificate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label"><i class="fa-solid fa-user me-2"></i>Owner Validation</label>
|
||||
<p id="modalValOwner" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label"><i class="fa-solid fa-user me-2"></i>SPV Validation</label>
|
||||
<p id="modalValSpv" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
<div class="col-md-4 mb-3">
|
||||
<label class="form-label"><i class="fa-solid fa-user me-2"></i>Manager Validation</label>
|
||||
<p id="modalValManager" class="form-control-plaintext border-bottom fw-bolder">-</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id='modalInfo'></div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-3">
|
||||
<div class="border rounded p-2" style="height: 500px; overflow: hidden;">
|
||||
<iframe id="certificatePreview" src="" style="width: 100%; height: 100%; border: none;"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fa-solid fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning text-dark" id="confirmValidateBtn">
|
||||
<i class="fa-solid fa-check"></i> Validate Certificate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('style') ?>
|
||||
<style>
|
||||
#certificatesTable {
|
||||
width: 100% !important;
|
||||
}
|
||||
#certificatesTable_wrapper {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('script') ?>
|
||||
@ -171,7 +166,7 @@
|
||||
$(function () {
|
||||
|
||||
let table = $('#certificatesTable').DataTable({
|
||||
order: [[5, 'asc']],
|
||||
order: [[3, 'asc']], // Order by Validation Column
|
||||
pageLength: 25,
|
||||
dom: '<"row"<"col-md-6"l>>rtip',
|
||||
responsive: true,
|
||||
@ -182,53 +177,43 @@ $(function () {
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
callback({
|
||||
data: result.map(cert => {
|
||||
let certid = cert.certid || '';
|
||||
let certname = cert.certname || '-';
|
||||
let productname = cert.productname || '-';
|
||||
let productnumber = cert.productnumber || '';
|
||||
let issuedateRaw = cert.issuedate || '';
|
||||
let expirydateRaw = cert.expirydate || '';
|
||||
let vendor = cert.vendor || '-';
|
||||
let isval = cert.isval || null;
|
||||
data: result.map((cert, index) => {
|
||||
|
||||
let certid = cert.cert_id || '';
|
||||
let certname = cert.cert_name || '-';
|
||||
let certnumber = cert.cert_number || '';
|
||||
let actid = cert.actid || '';
|
||||
let issuedateRaw = cert.issued_date || '';
|
||||
let status = cert.status; // Validation status
|
||||
let fullname = cert.fullname;
|
||||
let activity_subject = cert.activity_subject;
|
||||
|
||||
let issuedate = '-';
|
||||
let expirydate = '-';
|
||||
let statusBadge = '<span class="badge bg-warning text-dark">Need Validation</span>';
|
||||
let validationBadge = '';
|
||||
|
||||
if (isval != null) {
|
||||
if (issuedateRaw && issuedateRaw !== '0000-00-00') {
|
||||
issuedate = new Date(issuedateRaw).toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' });
|
||||
}
|
||||
if (issuedateRaw && issuedateRaw !== '0000-00-00') {
|
||||
let date = new Date(issuedateRaw);
|
||||
let day = String(date.getDate()).padStart(2, '0');
|
||||
let month = date.toLocaleString('en-US', { month: 'short' });
|
||||
let year = date.getFullYear();
|
||||
issuedate = `${day} ${month} ${year}`;
|
||||
}
|
||||
|
||||
if (expirydateRaw && expirydateRaw !== '0000-00-00') {
|
||||
expirydate = new Date(expirydateRaw).toLocaleDateString('en-US', { month: 'short', day: '2-digit', year: 'numeric' });
|
||||
let today = new Date();
|
||||
let expiryDate = new Date(expirydateRaw);
|
||||
let days = Math.ceil((expiryDate - today) / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (days < 0) {
|
||||
statusBadge = '<span class="badge bg-danger">Expired</span>';
|
||||
} else if (days <= 30) {
|
||||
statusBadge = '<span class="badge bg-info">Expiring Soon</span>';
|
||||
} else {
|
||||
statusBadge = '<span class="badge bg-success">Active</span>';
|
||||
}
|
||||
} else {
|
||||
statusBadge = '<span class="badge bg-secondary">N/A</span>';
|
||||
}
|
||||
if (status == 'unvalidated') {
|
||||
validationBadge = '<div class=""><span class="badge bg-warning text-dark">unvalidated</span></div>';
|
||||
} else {
|
||||
validationBadge = '<div class=""><span class="badge bg-success">validated</span></div>';
|
||||
}
|
||||
|
||||
return [
|
||||
`<strong>${certname}</strong><br><small class="text-muted">ID: ${certid}</small>`,
|
||||
`${productname}${productnumber ? '<br><small class="text-muted">SN: ' + productnumber + '</small>' : ''}`,
|
||||
`<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" style="color:#d43215b0;">Act ID - Nama AR - Nama User <i class="fa-solid fa-up-right-from-square"></i></a>`,
|
||||
`<strong>${certname}</strong><br><small class="text-muted">Cert# : ${certnumber}</small>`,
|
||||
`<a href="javascript:void(0)" class="activity-report-link text-decoration-none" data-certid="${certid}" data-actid="${actid}" style="color:#d43215b0;">#${actid} - ${activity_subject} <i class="fa-solid fa-up-right-from-square"></i></strong><br><small class="text-muted">Owner : ${fullname}</small></a>`,
|
||||
issuedate,
|
||||
expirydate,
|
||||
statusBadge,
|
||||
isval == null
|
||||
? `<div class="text-center"><button type="button" class="btn btn-warning text-dark btn-validate" data-certid="${certid}" data-certname="${certname}" data-productname="${productname}" data-productnumber="${productnumber}" data-issuedate="${issuedate}" data-expirydate="${expirydate}" data-vendor="${vendor}"><i class="fa-solid fa-check-double"></i></button></div>`
|
||||
: `<div class="text-center"><button type="button" class="btn btn-success btn-view" data-certid="${certid}"><i class="fa-regular fa-file-pdf"></i></button></div>`
|
||||
validationBadge,
|
||||
status == 'unvalidated'
|
||||
? `<div class="text-center"><button type="button" class="btn btn-sm btn-warning text-dark btn-validate-modal" data-certid="${certid}"><i class="fa-solid fa-triangle-exclamation me-2"></i>Need Validation</button></div>`
|
||||
: `<div class="text-center mb-1"><button type="button" class="btn btn-sm btn-info btn-validate-modal" data-certid="${certid}"><i class="fa-regular fa-eye me-2"></i>Detail</button></div>
|
||||
<div class="text-center"><button type="button" class="btn btn-sm btn-success btn-view" data-certnumber="${certnumber}"><i class="fa-regular fa-file-pdf me-2"></i>Generated PDF</button></div>`
|
||||
];
|
||||
})
|
||||
});
|
||||
@ -238,19 +223,26 @@ $(function () {
|
||||
callback({ data: [] });
|
||||
});
|
||||
},
|
||||
columnDefs: [{
|
||||
targets: 5,
|
||||
render: function (data, type) {
|
||||
if (type === 'sort') {
|
||||
if (data.includes('Need Validation')) return 1;
|
||||
if (data.includes('Expired')) return 2;
|
||||
if (data.includes('Expiring Soon')) return 3;
|
||||
if (data.includes('Active')) return 4;
|
||||
return 5;
|
||||
columnDefs: [
|
||||
{
|
||||
// Kondisi untuk Kolom 3 (Validation)
|
||||
targets: 3,
|
||||
render: function (data, type) {
|
||||
if (type === 'sort') {
|
||||
let val = data.toLowerCase();
|
||||
if (val.includes('unvalidated')) return 1;
|
||||
if (val.includes('validated')) return 2;
|
||||
return 3;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
{
|
||||
// Kondisi untuk Kolom 4 (Action)
|
||||
targets: [4],
|
||||
orderable: false
|
||||
}
|
||||
}]
|
||||
]
|
||||
});
|
||||
|
||||
$('#certificatesTable_filter').hide();
|
||||
@ -261,70 +253,107 @@ $(function () {
|
||||
});
|
||||
|
||||
// Type filter using DataTables column filter
|
||||
$('#typeFilter').on('change', function () {
|
||||
$('#productFilter').on('change', function () {
|
||||
let type = $(this).val();
|
||||
|
||||
// Filter by type column (index 1 - Certificate Name contains type info)
|
||||
if (type === '') {
|
||||
table.column(1).search('').draw();
|
||||
table.column(0).search('').draw();
|
||||
} else {
|
||||
// Capitalize first letter for search
|
||||
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
|
||||
table.column(1).search(typeText).draw();
|
||||
table.column(0).search(typeText).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Status filter
|
||||
$('#statusFilter').on('change', function () {
|
||||
let map = {
|
||||
active: 'Active',
|
||||
expired: 'Expired',
|
||||
expiring: 'Expiring Soon',
|
||||
isval: 'Need Validation'
|
||||
};
|
||||
table.column(5).search(map[this.value] || '').draw();
|
||||
$('#validationFilter').on('change', function () {
|
||||
let validation = $(this).val();
|
||||
if (validation === '') {
|
||||
table.column(3).search('').draw();
|
||||
} else if (validation === 'unval') {
|
||||
table.column(3).search('unv').draw();
|
||||
} else if (validation === 'valid') {
|
||||
table.column(3).search('^validated$', true, false).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Reset
|
||||
window.resetFilters = function () {
|
||||
$('#searchInput, #statusFilter').val('');
|
||||
table.search('').columns().search('').order([5,'asc']).draw();
|
||||
$('#searchInput, #productFilter, #validationFilter').val('');
|
||||
table.search('').columns().search('').draw();
|
||||
};
|
||||
|
||||
// View PDF
|
||||
$(document).on('click', '.btn-view', function () {
|
||||
let certid = $(this).data('certid');
|
||||
window.open('<?= base_url('certificates/installation/show/') ?>' + certid, '_blank');
|
||||
let certnumber = $(this).data('certnumber');
|
||||
window.open('<?= base_url('certificates/number/') ?>' + certnumber, '_blank');
|
||||
});
|
||||
|
||||
// Activity report
|
||||
$(document).on('click', '.activity-report-link', function () {
|
||||
let certid = $(this).data('certid');
|
||||
let actid = $(this).data('actid');
|
||||
window.open(
|
||||
'<?= base_url('certificates/installation/activity/') ?>' + certid,
|
||||
'<?= base_url('activities/detail/') ?>' + actid,
|
||||
'_blank',
|
||||
'width=1200,height=800,scrollbars=yes,resizable=yes'
|
||||
);
|
||||
});
|
||||
|
||||
// Open modal
|
||||
$(document).on('click', '.btn-validate', function () {
|
||||
$(document).on('click', '.btn-validate-modal', function () {
|
||||
|
||||
let btn = $(this);
|
||||
let certid = btn.data('certid');
|
||||
|
||||
$('#modalCertId').text(btn.data('certid'));
|
||||
$('#modalCertName').text(btn.data('certname'));
|
||||
$('#modalProductName').text(btn.data('productname'));
|
||||
$('#modalProductNumber').text(btn.data('productnumber'));
|
||||
$('#modalIssueDate').text(btn.data('issuedate'));
|
||||
$('#modalExpiryDate').text(btn.data('expirydate'));
|
||||
$('#modalVendor').text(btn.data('vendor'));
|
||||
// POST API call to fetch certificate data
|
||||
$.post(
|
||||
'<?= base_url('certificates/api/showinstallation') ?>',
|
||||
{ certid },
|
||||
function (data) {
|
||||
$('#modalCertName').text(data.cert_name || '-');
|
||||
$('#modalCertNumber').text(data.cert_number || '-');
|
||||
$('#modalProductName').text(data.productname || '-');
|
||||
$('#modalProductNumber').text(data.productnumber || '-');
|
||||
$('#modalIssueDate').text(data.issued_date || '-');
|
||||
$('#modalSiteName').text(data.sitename || '-');
|
||||
|
||||
$('#confirmValidateBtn').data('certid', btn.data('certid'));
|
||||
$('#certificatePreview').attr(
|
||||
'src',
|
||||
'<?= base_url('certificates/installation/show/') ?>' + btn.data('certid')
|
||||
);
|
||||
// Cek status validasi
|
||||
const isValid = data.status === 'validated';
|
||||
const theme = isValid ? 'success' : 'warning';
|
||||
const icon = isValid ? 'fa-regular fa-circle-check' : 'fa-solid fa-triangle-exclamation';
|
||||
const note = isValid
|
||||
? 'Sertifikat Sudah Divalidasi'
|
||||
: 'Review data berikut dengan teliti, setelah divalidasi maka sertifikat akan dinyatakan <strong>Valid</strong> dan <strong>sah secara sistem.</strong>';
|
||||
|
||||
$('#modalHeader').removeClass('bg-warning bg-success').addClass(`bg-${theme} text-dark`);
|
||||
$('#modalValidation').html(
|
||||
`<span class="badge bg-${theme} text-dark py-2 px-3">
|
||||
<i class="${icon} me-2"></i>${data.status || '-'}
|
||||
</span>`
|
||||
);
|
||||
|
||||
$('#modalInfo').html(
|
||||
`<div class="alert alert-${theme} border-0 shadow-sm d-flex align-items-center">
|
||||
<i class="${icon} fs-4 me-3"></i>
|
||||
<div>
|
||||
<strong>Validation Note:</strong><br>
|
||||
${note}
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
|
||||
$('#modalActivity').text(data.actid ? `#${data.actid} - ${data.subject || '-'}` : '-');
|
||||
$('#modalActivityLink').attr('data-actid', data.actid || '');
|
||||
$('#modalValOwner').html(data.user_validation_at ? `${data.username} - ${data.user_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||
$('#modalValSpv').html(data.spv_validation_at ? `${data.spvname} - ${data.spv_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||
$('#modalValManager').html(data.manager_validation_at ? `${data.managername} - ${data.manager_validation_at}<i class="fa-solid fa-circle-check text-success ms-2"></i>` : '-');
|
||||
},
|
||||
'json'
|
||||
).fail(function () {
|
||||
console.error('Error fetching certificate data');
|
||||
});
|
||||
|
||||
// INI JANGAN DIUBAH
|
||||
$('#confirmValidateBtn').data('certid', certid);
|
||||
$('#certificatePreview').attr('src','<?= base_url('certificates/installation/show/') ?>' + certid);
|
||||
|
||||
$('#validateModal').modal('show');
|
||||
});
|
||||
@ -337,43 +366,23 @@ $(function () {
|
||||
if (!confirm('Are you sure?')) return;
|
||||
|
||||
$.post(
|
||||
'<?= base_url('certificates/api/validateCertificate') ?>',
|
||||
'<?= base_url('certificates/api/validatecertificate') ?>',
|
||||
{ certid, certificateType},
|
||||
function (response) {
|
||||
|
||||
if (response.success) {
|
||||
$('#validateModal').modal('hide');
|
||||
alert(response.message);
|
||||
|
||||
// Generate and save PDF after successful validation
|
||||
$.post(
|
||||
'<?= base_url('certificates/api/generatepdf') ?>',
|
||||
{ certid, certificateType },
|
||||
function (pdfResponse) {
|
||||
if (pdfResponse.success) {
|
||||
alert('PDF generated and saved successfully!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Validation successful but PDF generation failed: ' + (pdfResponse.message || 'Unknown error'));
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
'json'
|
||||
).fail(function () {
|
||||
alert('Validation successful but failed to generate PDF');
|
||||
location.reload();
|
||||
});
|
||||
|
||||
location.reload();
|
||||
} else {
|
||||
alert(response.message || 'Validation failed');
|
||||
}
|
||||
|
||||
}, 'json'
|
||||
).fail(function () {
|
||||
$('#validateModal').modal('hide');
|
||||
alert('Server error.');
|
||||
).fail(function (xhr) {
|
||||
console.log(xhr);
|
||||
alert(xhr.responseText);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@ -1,545 +0,0 @@
|
||||
<?= $this->extend('layouts/main.php') ?>
|
||||
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<div class="page-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row page-titles">
|
||||
<div class="col-md-5 align-self-center">
|
||||
<h4 class="text-themecolor">Certificates Maintenance Management</h4>
|
||||
</div>
|
||||
<div class="col-md-7 align-self-center text-end">
|
||||
<button type="button" class="btn btn-info text-white btn-sm" data-bs-toggle="modal" data-bs-target="#createModal">
|
||||
<i class="fas fa-plus-circle"></i> Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="col-12 mb-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="Search certificates by name, product, type, vendor, or dates...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="statusFilter" class="form-select form-select-sm">
|
||||
<option value="">All Status</option>
|
||||
<option value="active">Active</option>
|
||||
<option value="expired">Expired</option>
|
||||
<option value="expiring">Expiring Soon</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<select id="typeFilter" class="form-select form-select-sm">
|
||||
<option value="">All Types</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<button onclick="resetFilters()" class="btn btn-secondary btn-sm w-100">
|
||||
<i class="fas fa-redo"></i> Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="certificatesTable" class="table table-striped table-hover border">
|
||||
<thead class="table-primary">
|
||||
<tr>
|
||||
<th class="text-center" style="width: 5%;">No</th>
|
||||
<th style="width: 15%;">Certificate Name</th>
|
||||
<th style="width: 15%;">Product/Equipment</th>
|
||||
<th style="width: 12%;">Type</th>
|
||||
<th style="width: 12%;">Issue Date</th>
|
||||
<th style="width: 12%;">Expiry Date</th>
|
||||
<th style="width: 10%;">Status</th>
|
||||
<th style="width: 10%;">Vendor</th>
|
||||
<th class="text-center" style="width: 9%;">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if(isset($certificates) && !empty($certificates)) {
|
||||
$no = 1;
|
||||
foreach($certificates as $cert) {
|
||||
$certid = $cert['certid'] ?? '';
|
||||
$certname = $cert['certname'] ?? '-';
|
||||
$productname = $cert['productname'] ?? '-';
|
||||
$productnumber = $cert['productnumber'] ?? '';
|
||||
$type = $cert['type'] ?? '-';
|
||||
$issuedate = $cert['issuedate'] ?? '';
|
||||
$expirydate = $cert['expirydate'] ?? '';
|
||||
$vendor = $cert['vendor'] ?? '-';
|
||||
|
||||
// Format dates
|
||||
if($issuedate && $issuedate != '0000-00-00') {
|
||||
$issuedate = date('M d, Y', strtotime($issuedate));
|
||||
} else {
|
||||
$issuedate = '-';
|
||||
}
|
||||
|
||||
if($expirydate && $expirydate != '0000-00-00') {
|
||||
$expirydate = date('M d, Y', strtotime($expirydate));
|
||||
// Check expiry status
|
||||
$today = date('Y-m-d');
|
||||
$expiryCheck = date('Y-m-d', strtotime($cert['expirydate']));
|
||||
$daysUntilExpiry = (strtotime($expiryCheck) - strtotime($today)) / (60 * 60 * 24);
|
||||
|
||||
if($daysUntilExpiry < 0) {
|
||||
$statusBadge = '<span class="badge bg-danger">Expired</span>';
|
||||
$statusClass = 'expired';
|
||||
} elseif($daysUntilExpiry <= 30) {
|
||||
$statusBadge = '<span class="badge bg-warning text-dark">Expiring Soon</span>';
|
||||
$statusClass = 'expiring';
|
||||
} else {
|
||||
$statusBadge = '<span class="badge bg-success">Active</span>';
|
||||
$statusClass = 'active';
|
||||
}
|
||||
} else {
|
||||
$expirydate = '-';
|
||||
$statusBadge = '<span class="badge bg-secondary">N/A</span>';
|
||||
$statusClass = '';
|
||||
}
|
||||
|
||||
// Type badge
|
||||
$typeBadge = '';
|
||||
switch(strtolower($type)) {
|
||||
case 'calibration':
|
||||
$typeBadge = '<span class="badge bg-info">Calibration</span>';
|
||||
break;
|
||||
case 'training':
|
||||
$typeBadge = '<span class="badge bg-primary">Training</span>';
|
||||
break;
|
||||
case 'maintenance':
|
||||
$typeBadge = '<span class="badge bg-warning text-dark">Maintenance</span>';
|
||||
break;
|
||||
default:
|
||||
$typeBadge = '<span class="badge bg-secondary">' . htmlspecialchars($type) . '</span>';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-center"><?= $no++; ?></td>
|
||||
<td>
|
||||
<strong><?= htmlspecialchars($certname) ?></strong>
|
||||
<br>
|
||||
<small class="text-muted">ID: <?= $certid ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<?= htmlspecialchars($productname) ?>
|
||||
<?php if($productnumber): ?>
|
||||
<br><small class="text-muted">SN: <?= htmlspecialchars($productnumber) ?></small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?= $typeBadge ?></td>
|
||||
<td><?= $issuedate ?></td>
|
||||
<td><?= $expirydate ?></td>
|
||||
<td><?= $statusBadge ?></td>
|
||||
<td><?= htmlspecialchars($vendor) ?></td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button type="button" class="btn btn-success btn-view" data-certid="<?= $certid ?>" data-certtype="<?= $type ?>" title="View PDF">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-edit" data-certid="<?= $certid ?>" title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-danger btn-delete" data-certid="<?= $certid ?>" data-certname="<?= htmlspecialchars($certname) ?>" title="Delete">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
} else {
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="9" class="text-center py-5">
|
||||
<i class="fas fa-certificate fa-3x text-muted mb-3"></i>
|
||||
<p class="text-muted">No certificates found</p>
|
||||
<button type="button" class="btn btn-info text-white btn-sm" data-bs-toggle="modal" data-bs-target="#createModal">
|
||||
<i class="fas fa-plus-circle"></i> Add First Certificate
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Modal -->
|
||||
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-info text-white">
|
||||
<h5 class="modal-title" id="createModalLabel">
|
||||
<i class="fas fa-plus-circle"></i> Create New Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form id="createForm" action="<?= base_url('certificates/create') ?>" method="post">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="certname" class="form-label">Certificate Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="certname" name="certname" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="type" class="form-label">Type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="type" name="type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="productid" class="form-label">Product/Equipment</label>
|
||||
<select class="form-select select2" id="productid" name="productid">
|
||||
<option value="">Select Product</option>
|
||||
<?php if(isset($products)): ?>
|
||||
<?php foreach($products as $product): ?>
|
||||
<option value="<?= $product['productid'] ?>">
|
||||
<?= htmlspecialchars($product['productname']) ?>
|
||||
<?php if($product['productnumber']): ?>
|
||||
(SN: <?= htmlspecialchars($product['productnumber']) ?>)
|
||||
<?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="vendor" class="form-label">Vendor/Provider</label>
|
||||
<input type="text" class="form-control" id="vendor" name="vendor">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="issuedate" class="form-label">Issue Date</label>
|
||||
<input type="date" class="form-control" id="issuedate" name="issuedate">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="expirydate" class="form-label">Expiry Date</label>
|
||||
<input type="date" class="form-control" id="expirydate" name="expirydate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="attachment" class="form-label">Attachment</label>
|
||||
<input type="file" class="form-control" id="attachment" name="attachment" accept=".pdf,.jpg,.jpeg,.png">
|
||||
<small class="text-muted">Allowed: PDF, JPG, PNG (Max 5MB)</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-info text-white">
|
||||
<i class="fas fa-save"></i> Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-warning text-dark">
|
||||
<h5 class="modal-title" id="editModalLabel">
|
||||
<i class="fas fa-edit"></i> Edit Certificate
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form id="editForm" action="<?= base_url('certificates/update') ?>" method="post">
|
||||
<input type="hidden" id="edit_certid" name="certid">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_certname" class="form-label">Certificate Name <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="edit_certname" name="certname" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_type" class="form-label">Type <span class="text-danger">*</span></label>
|
||||
<select class="form-select" id="edit_type" name="type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="calibration">Calibration</option>
|
||||
<option value="training">Training</option>
|
||||
<option value="maintenance">Maintenance</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_productid" class="form-label">Product/Equipment</label>
|
||||
<select class="form-select select2" id="edit_productid" name="productid">
|
||||
<option value="">Select Product</option>
|
||||
<?php if(isset($products)): ?>
|
||||
<?php foreach($products as $product): ?>
|
||||
<option value="<?= $product['productid'] ?>">
|
||||
<?= htmlspecialchars($product['productname']) ?>
|
||||
<?php if($product['productnumber']): ?>
|
||||
(SN: <?= htmlspecialchars($product['productnumber']) ?>)
|
||||
<?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_vendor" class="form-label">Vendor/Provider</label>
|
||||
<input type="text" class="form-control" id="edit_vendor" name="vendor">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_issuedate" class="form-label">Issue Date</label>
|
||||
<input type="date" class="form-control" id="edit_issuedate" name="issuedate">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_expirydate" class="form-label">Expiry Date</label>
|
||||
<input type="date" class="form-control" id="edit_expirydate" name="expirydate">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="edit_description" class="form-label">Description</label>
|
||||
<textarea class="form-control" id="edit_description" name="description" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<button type="submit" class="btn btn-warning text-dark">
|
||||
<i class="fas fa-save"></i> Update
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-white">
|
||||
<h5 class="modal-title" id="deleteModalLabel">
|
||||
<i class="fas fa-exclamation-triangle"></i> Confirm Delete
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Are you sure you want to delete this certificate?</p>
|
||||
<div class="alert alert-warning">
|
||||
<strong>Certificate:</strong> <span id="deleteCertName"></span>
|
||||
</div>
|
||||
<p class="text-muted small">This action cannot be undone.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="fas fa-times"></i> Cancel
|
||||
</button>
|
||||
<form id="deleteForm" action="<?= base_url('certificates/delete') ?>" method="post">
|
||||
<input type="hidden" id="delete_certid" name="certid">
|
||||
<button type="submit" class="btn btn-danger text-white">
|
||||
<i class="fas fa-trash"></i> Delete
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('script') ?>
|
||||
<script>
|
||||
$(function () {
|
||||
// Store DataTable instance
|
||||
var table = null;
|
||||
|
||||
// Initialize DataTable
|
||||
table = $('#certificatesTable').DataTable({
|
||||
"order": [[0, "asc"]],
|
||||
"pageLength": 25,
|
||||
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
|
||||
"language": {
|
||||
"emptyTable": "No certificates available",
|
||||
"info": "Showing _START_ to _END_ of _TOTAL_ certificates",
|
||||
"infoEmpty": "No certificates found",
|
||||
"infoFiltered": "(filtered from _MAX_ total certificates)"
|
||||
},
|
||||
"dom": '<"row"<"col-md-6"l>>rtip',
|
||||
"columnDefs": [
|
||||
{ "orderable": false, "targets": [8] }, // Disable sorting on Action column
|
||||
{ "searchable": true, "targets": [0, 1, 2, 3, 4, 5, 6, 7] } // Enable search on all columns except Action
|
||||
]
|
||||
});
|
||||
|
||||
// Hide default DataTables search
|
||||
$('#certificatesTable_filter').hide();
|
||||
|
||||
// Initialize Select2
|
||||
$('.select2').select2({
|
||||
theme: 'bootstrap-5',
|
||||
width: '100%',
|
||||
dropdownParent: $('.modal')
|
||||
});
|
||||
|
||||
// Custom search functionality
|
||||
$('#searchInput').on('keyup', function() {
|
||||
var searchValue = $(this).val().toLowerCase();
|
||||
table.search(searchValue).draw();
|
||||
});
|
||||
|
||||
// Status filter using DataTables column filter
|
||||
$('#statusFilter').on('change', function() {
|
||||
var status = $(this).val();
|
||||
|
||||
// Filter by status column (index 6)
|
||||
if(status === '') {
|
||||
table.column(6).search('').draw();
|
||||
} else {
|
||||
// Search for the badge text in status column
|
||||
var statusText = '';
|
||||
switch(status) {
|
||||
case 'active':
|
||||
statusText = 'Active';
|
||||
break;
|
||||
case 'expired':
|
||||
statusText = 'Expired';
|
||||
break;
|
||||
case 'expiring':
|
||||
statusText = 'Expiring Soon';
|
||||
break;
|
||||
}
|
||||
table.column(6).search(statusText).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Type filter using DataTables column filter
|
||||
$('#typeFilter').on('change', function() {
|
||||
var type = $(this).val();
|
||||
|
||||
// Filter by type column (index 3)
|
||||
if(type === '') {
|
||||
table.column(3).search('').draw();
|
||||
} else {
|
||||
// Capitalize first letter for search
|
||||
var typeText = type.charAt(0).toUpperCase() + type.slice(1);
|
||||
table.column(3).search(typeText).draw();
|
||||
}
|
||||
});
|
||||
|
||||
// Reset filters
|
||||
window.resetFilters = function() {
|
||||
$('#searchInput').val('');
|
||||
$('#statusFilter').val('');
|
||||
$('#typeFilter').val('');
|
||||
|
||||
// Reset DataTables search and filters
|
||||
table.search('').columns().search('').draw();
|
||||
|
||||
// Re-apply default ordering
|
||||
table.order([5, 'asc']).draw();
|
||||
};
|
||||
|
||||
// View button click - Open PDF in new tab based on certificate type
|
||||
$(document).on('click', '.btn-view', function() {
|
||||
var certid = $(this).data('certid');
|
||||
var certType = $(this).data('certtype');
|
||||
|
||||
var url = '';
|
||||
switch(certType) {
|
||||
case 'training':
|
||||
url = '<?= base_url('certificates/training') ?>/' + certid;
|
||||
break;
|
||||
case 'calibration':
|
||||
url = '<?= base_url('certificates/calibrate') ?>/' + certid;
|
||||
break;
|
||||
case 'maintenance':
|
||||
url = '<?= base_url('certificates/maintenance') ?>/' + certid;
|
||||
break;
|
||||
default:
|
||||
url = '<?= base_url('certificates/view') ?>/' + certid;
|
||||
}
|
||||
|
||||
window.open(url, '_blank');
|
||||
});
|
||||
|
||||
// Edit button click
|
||||
$(document).on('click', '.btn-edit', function() {
|
||||
var certid = $(this).data('certid');
|
||||
$('#edit_certid').val(certid);
|
||||
$('#editModal').modal('show');
|
||||
|
||||
// Load certificate data via AJAX
|
||||
$.get('<?= base_url('certificates/get') ?>/' + certid, function(data) {
|
||||
$('#edit_certname').val(data.certname);
|
||||
$('#edit_type').val(data.type);
|
||||
$('#edit_productid').val(data.productid).trigger('change');
|
||||
$('#edit_vendor').val(data.vendor);
|
||||
$('#edit_issuedate').val(data.issuedate);
|
||||
$('#edit_expirydate').val(data.expirydate);
|
||||
$('#edit_description').val(data.description);
|
||||
}).fail(function() {
|
||||
$('#editModal').modal('hide');
|
||||
alert('Failed to load certificate data.');
|
||||
});
|
||||
});
|
||||
|
||||
// Delete button click
|
||||
$(document).on('click', '.btn-delete', function() {
|
||||
var certid = $(this).data('certid');
|
||||
var certname = $(this).data('certname');
|
||||
$('#delete_certid').val(certid);
|
||||
$('#deleteCertName').text(certname);
|
||||
$('#deleteModal').modal('show');
|
||||
});
|
||||
|
||||
// Form validation
|
||||
$('#createForm, #editForm').on('submit', function(e) {
|
||||
var form = this;
|
||||
if(form.checkValidity()) {
|
||||
// Form is valid, submit
|
||||
return true;
|
||||
}
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
form.classList.add('was-validated');
|
||||
});
|
||||
|
||||
// Date picker enhancement
|
||||
$('input[type="date"]').on('focus', function() {
|
||||
this.showPicker();
|
||||
});
|
||||
|
||||
// Re-attach event handlers after DataTables pagination/draw
|
||||
table.on('draw.dt', function() {
|
||||
// Event handlers are already attached using $(document).on(), so no need to re-attach
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
@ -41,10 +41,10 @@
|
||||
<li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-certificate"></i><span class='hide-menu'>Certificates</span> </a>
|
||||
<ul aria-expanded="false" class="collapse">
|
||||
<li><a href="<?=base_url();?>certificates/maintenance">Maintenance</a></li>
|
||||
<!-- <li><a href="<?=base_url();?>certificates/installation">Installation</a></li>
|
||||
<li><a href="<?=base_url();?>certificates/training">Training</a></li>
|
||||
<li><a href="<?=base_url();?>certificates/calibration">Callibration</a></li>
|
||||
<li><a href="<?=base_url();?>certificates/official-report">Official Report</a></li> -->
|
||||
<li><a href="<?=base_url();?>certificates/installation">Installation</a></li>
|
||||
<!-- <li><a href="<?=base_url();?>certificates/training">Training</a></li> -->
|
||||
<!-- <li><a href="<?=base_url();?>certificates/calibration">Callibration</a></li> -->
|
||||
<!-- <li><a href="<?=base_url();?>certificates/official-report">Official Report</a></li> -->
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user