Update Certificare V1

This commit is contained in:
mikael-zakaria 2026-02-19 08:53:25 +07:00
parent d765b82c16
commit 1328fed57b
19 changed files with 6620 additions and 3 deletions

View File

@ -206,6 +206,27 @@ $routes->match(['get', 'post'], '/guidebook/edit/(:any)', 'Guidebook::edit/$1');
$routes->get('/guidebook/delete/(:num)', 'Guidebook::delete/$1'); $routes->get('/guidebook/delete/(:num)', 'Guidebook::delete/$1');
// Certificates
$routes->group('certificates', function($routes) {
// Untuk Index
$routes->get('/', 'Certificates::index');
// Untuk Index Tiap Menu
$routes->get('training', 'Certificates::trainingIndex');
$routes->get('calibration', 'Certificates::calibrateIndex');
$routes->get('maintenance', 'Certificates::maintenanceIndex');
// Untuk View Cerificate
$routes->get('training/show/(:any)', 'Certificates::createTraining/$1');
$routes->get('calibration/show/(:any)/(:any)', 'Certificates::createCalibrate/$1/$2');
$routes->get('maintenance/show/(:any)', 'Certificates::createMaintenance/$1');
// $routes->get('view/(:any)', 'Certificates::view/$1');
// $routes->get('get/(:any)', 'Certificates::get/$1');
});
// Groups // Groups
$routes->get('/mailgroups', 'Mailgroups::index'); $routes->get('/mailgroups', 'Mailgroups::index');

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,655 @@
<?= $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 Calibration 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>
</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="">
<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 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-certprod="<?= $productname ?>" data-certtype="<?= $type ?>"
title="View PDF">
<i class="fas fa-file-pdf"></i>
</button>
</div>
</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-xl 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> &nbsp;Create New Certificate Calibration
</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="address" class="form-label">Address</label>
<input type="text" class="form-control" id="address" name="address">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="issuedate" class="form-label">Start Date <span
class="text-danger">*</span></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 <span
class="text-danger">*</span></label>
<input type="date" class="form-control" id="expirydate" name="expirydate">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="type" class="form-label">Site <span class="text-danger">*</span></label>
<select class="form-select select2" id="type" name="type" required>
<option value=''>-- Choose one --</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="productid" class="form-label">Product/Equipment <span
class="text-danger">*</span></label>
<select class="form-select select2" id="productid" name="productid">
<option value=''>-- Choose one --</option>
</select>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="reqmaterial" class="form-label">Required Material</label>
<textarea class="form-control" id="reqmaterial" name="reqmaterial" rows="4"></textarea>
</div>
<div class="col-md-4 mb-3">
<label for="procedure" class="form-label">Procedure</label>
<textarea class="form-control" id="procedure" name="procedure" rows="4"></textarea>
</div>
<div class="col-md-4 mb-3">
<label for="requirement" class="form-label">Requirement</label>
<textarea class="form-control" id="requirement" name="requirement" rows="4"></textarea>
</div>
</div>
<div class="row">
<div class="controls">
<label>Nama Kolom (koma):
<input type="text" id="namaKolom" placeholder="No, Nama, Alamat"
value="No, Nama, Pekerjaan">
</label>
<label>Jumlah Baris:
<input type="number" id="inputBaris" value="3" min="1" style="width: 50px;">
</label>
<button type="button" onclick="buatTabelCustom()">Generate Tabel</button>
<button type="button" onclick="ambilData()" style="background: #4CAF50;">Cetak Data ke
Konsol</button>
<button type="button" onclick="resetTabel()" style="background: #dc3545;">Reset
Tabel</button>
</div>
</div>
<div class="row">
<div id="containerTabel"></div>
</div>
<style>
/* Styling untuk tabel yang di-generate */
#myTable {
width: 100%;
border-collapse: collapse;
margin-top: 15px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
#myTable thead {
background-color: #17a2b8;
color: white;
}
#myTable th {
padding: 12px;
text-align: left;
font-weight: 600;
border: 1px solid #dee2e6;
}
#myTable tbody tr {
border-bottom: 1px solid #dee2e6;
}
#myTable tbody tr:hover {
background-color: #f8f9fa;
}
#myTable td {
padding: 10px;
border: 1px solid #dee2e6;
min-width: 100px;
min-height: 35px;
}
#myTable td:focus {
outline: 2px solid #17a2b8;
background-color: #e9ecef;
}
#myTable td[contenteditable="true"]:hover {
background-color: #f1f8ff;
cursor: text;
}
/* Styling untuk container tabel */
#containerTabel {
margin-top: 20px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 8px;
border: 1px solid #dee2e6;
}
/* Styling untuk controls */
.controls {
display: flex;
align-items: center;
gap: 15px;
flex-wrap: wrap;
padding: 15px;
background-color: #e9ecef;
border-radius: 8px;
margin-bottom: 15px;
}
.controls label {
margin: 0;
font-weight: 500;
}
.controls input[type="text"],
.controls input[type="number"] {
padding: 8px 12px;
border: 1px solid #ced4da;
border-radius: 4px;
margin-left: 8px;
}
.controls button {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
transition: all 0.3s ease;
}
.controls button:first-of-type {
background-color: #17a2b8;
color: white;
}
.controls button:first-of-type:hover {
background-color: #138496;
}
.controls button:last-of-type {
background-color: #28a745;
color: white;
}
.controls button:last-of-type:hover {
background-color: #218838;
}
.controls button:nth-last-of-type(2) {
background-color: #dc3545;
color: white;
}
.controls button:nth-last-of-type(2):hover {
background-color: #c82333;
}
</style>
<!-- <div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="2"></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-info text-white">
<i class="fas fa-save"></i> Save
</button>
</div>
</form>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
$(function () {
// Store DataTable instance
let 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 () {
let searchValue = $(this).val().toLowerCase();
table.search(searchValue).draw();
});
// Status filter using DataTables column filter
$('#statusFilter').on('change', function () {
let 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
let 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 () {
let type = $(this).val();
// Filter by type column (index 3)
if (type === '') {
table.column(3).search('').draw();
} else {
// Capitalize first letter for search
let 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 () {
let certid = $(this).data('certid');
// let certType = $(this).data('certtype');s
let certProd = $(this).data('certprod');
let url = '';
url = '<?= base_url('certificates/calibration/show') ?>/' + certid + '/' + certProd;
// switch (certType) {
// case 'training':
// url = '<?= base_url('certificates/training/show') ?>/' + certid;
// break;
// case 'calibration':
// url = '<?= base_url('certificates/calibration/show') ?>/' + certid;
// break;
// case 'maintenance':
// url = '<?= base_url('certificates/maintenance/show') ?>/' + certid;
// break;
// default:
// url = '<?= base_url('certificates/view') ?>/' + certid;
// }
window.open(url, '_blank');
});
// Print button
$('#btnPrint').on('click', function () {
window.print();
});
// 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
});
});
function buatTabelCustom() {
const headerInput = document.getElementById('namaKolom').value;
const jumlahBaris = document.getElementById('inputBaris').value;
const kontainer = document.getElementById('containerTabel');
const daftarKolom = headerInput.split(',').map(item => item.trim());
if (headerInput === "" || daftarKolom[0] === "") {
alert("Mohon isi nama kolom terlebih dahulu!");
return;
}
kontainer.innerHTML = "";
const tabel = document.createElement('table');
tabel.id = "myTable";
tabel.className = "table table-bordered table-striped table-hover";
tabel.style.width = "100%";
tabel.style.borderCollapse = "collapse";
tabel.style.backgroundColor = "#fff";
tabel.style.boxShadow = "0 2px 4px rgba(0,0,0,0.1)";
// --- HEADER ---
const thead = document.createElement('thead');
thead.style.backgroundColor = "#17a2b8";
thead.style.color = "white";
const barisHeader = document.createElement('tr');
daftarKolom.forEach(teksKolom => {
const th = document.createElement('th');
th.textContent = teksKolom;
th.style.padding = "12px";
th.style.textAlign = "left";
th.style.fontWeight = "600";
th.style.border = "1px solid #dee2e6";
barisHeader.appendChild(th);
});
thead.appendChild(barisHeader);
tabel.appendChild(thead);
// --- BODY (EDITABLE) ---
const tbody = document.createElement('tbody');
for (let i = 1; i <= jumlahBaris; i++) {
const baris = document.createElement('tr');
baris.style.borderBottom = "1px solid #dee2e6";
baris.style.transition = "background-color 0.2s ease";
daftarKolom.forEach(() => {
const td = document.createElement('td');
td.contentEditable = "true";
td.textContent = "";
td.style.padding = "10px";
td.style.border = "1px solid #dee2e6";
td.style.minWidth = "100px";
td.style.minHeight = "35px";
td.style.cursor = "text";
// Add hover effect
td.addEventListener('mouseenter', function () {
this.style.backgroundColor = "#f1f8ff";
});
td.addEventListener('mouseleave', function () {
this.style.backgroundColor = "";
});
// Add focus effect
td.addEventListener('focus', function () {
this.style.outline = "2px solid #17a2b8";
this.style.backgroundColor = "#e9ecef";
});
td.addEventListener('blur', function () {
this.style.outline = "none";
this.style.backgroundColor = "";
});
baris.appendChild(td);
});
tbody.appendChild(baris);
}
tabel.appendChild(tbody);
kontainer.appendChild(tabel);
}
// Fungsi tambahan untuk membuktikan data bisa diambil
function ambilData() {
const tabel = document.getElementById('myTable');
if (!tabel) return;
const rows = Array.from(tabel.querySelectorAll('tbody tr'));
const data = rows.map(row => {
return Array.from(row.querySelectorAll('td')).map(td => td.textContent);
});
console.log("Data Tabel:", data);
alert("Data sudah dicetak di Console (F12) dalam bentuk Array.");
}
// Fungsi untuk mereset/hapus tabel
function resetTabel() {
const kontainer = document.getElementById('containerTabel');
if (kontainer) {
kontainer.innerHTML = "";
// alert("Tabel berhasil dihapus!");
}
}
</script>
<?= $this->endSection() ?>

View File

@ -0,0 +1,577 @@
<?= $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() ?>

View File

@ -0,0 +1,361 @@
<?= $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>
<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="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="">
<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 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%;">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 = '';
}
?>
<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><?= $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>
</div>
</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-xl 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> &nbsp;Create Certificate Maintenance
</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="certtype" class="form-label">Type Sertifikat</label>
<input type="text" class="form-control" id="certtype" name="certtype">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="issuedate" class="form-label">Start Date <span
class="text-danger">*</span></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 <span
class="text-danger">*</span></label>
<input type="date" class="form-control" id="expirydate" name="expirydate">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="type" class="form-label">Site <span class="text-danger">*</span></label>
<select class="form-select select2" id="type" name="type" required>
<option value=''>-- Choose one --</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="productid" class="form-label">Product/Equipment <span
class="text-danger">*</span></label>
<select class="form-select select2" id="productid" name="productid">
<option value=''>-- Choose one --</option>
</select>
</div>
</div>
<!-- <div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="2"></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-info text-white">
<i class="fas fa-save"></i> Save
</button>
</div>
</form>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
$(function () {
// Store DataTable instance
let 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": [7]
}, // Disable sorting on Action column
{
"searchable": true,
"targets": [0, 1, 2, 3, 4, 5, 6]
} // 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 () {
let searchValue = $(this).val().toLowerCase();
table.search(searchValue).draw();
});
// Status filter using DataTables column filter
$('#statusFilter').on('change', function () {
let 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
let 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 () {
let type = $(this).val();
// Filter by type column (index 3)
if (type === '') {
table.column(2).search('').draw();
} else {
// Capitalize first letter for search
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
table.column(2).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 () {
let certid = $(this).data('certid');
let certType = $(this).data('certtype');
let url = '<?= base_url('certificates/maintenance/show/') ?>' + certid;
window.open(url, '_blank');
});
// Print button
$('#btnPrint').on('click', function () {
window.print();
});
// 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() ?>

View File

@ -0,0 +1,361 @@
<?= $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 Training 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>
</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="">
<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 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%;">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 = '';
}
?>
<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><?= $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>
</div>
</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-xl 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> &nbsp;Create Certificate Training
</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="certtype" class="form-label">Type Sertifikat</label>
<input type="text" class="form-control" id="certtype" name="certtype">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="issuedate" class="form-label">Start Date <span
class="text-danger">*</span></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 <span
class="text-danger">*</span></label>
<input type="date" class="form-control" id="expirydate" name="expirydate">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="type" class="form-label">Site <span class="text-danger">*</span></label>
<select class="form-select select2" id="type" name="type" required>
<option value=''>-- Choose one --</option>
</select>
</div>
<div class="col-md-6 mb-3">
<label for="productid" class="form-label">Product/Equipment <span
class="text-danger">*</span></label>
<select class="form-select select2" id="productid" name="productid">
<option value=''>-- Choose one --</option>
</select>
</div>
</div>
<!-- <div class="mb-3">
<label for="description" class="form-label">Description</label>
<textarea class="form-control" id="description" name="description" rows="2"></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-info text-white">
<i class="fas fa-save"></i> Save
</button>
</div>
</form>
</div>
</div>
</div>
<?= $this->endSection() ?>
<?= $this->section('script') ?>
<script>
$(function () {
// Store DataTable instance
let 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": [7]
}, // Disable sorting on Action column
{
"searchable": true,
"targets": [0, 1, 2, 3, 4, 5, 6]
} // 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 () {
let searchValue = $(this).val().toLowerCase();
table.search(searchValue).draw();
});
// Status filter using DataTables column filter
$('#statusFilter').on('change', function () {
let 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
let 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 () {
let type = $(this).val();
// Filter by type column (index 3)
if (type === '') {
table.column(2).search('').draw();
} else {
// Capitalize first letter for search
let typeText = type.charAt(0).toUpperCase() + type.slice(1);
table.column(2).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 () {
let certid = $(this).data('certid');
let certType = $(this).data('certtype');
let url = '<?= base_url('certificates/training/show/') ?>' + certid;
window.open(url, '_blank');
});
// Print button
$('#btnPrint').on('click', function () {
window.print();
});
// 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() ?>

View File

@ -0,0 +1,403 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 1px 0;
padding: 0;
font-size: 13px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 1px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 10px;
margin-top: 10px;
}
.box h4 {
margin: 0;
}
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 1px 6px;
text-align: center;
}
.result-table td.param {
text-align: left;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.detail-table {
width: 100%;
border-collapse: collapse;
}
.detail-table td {
padding: 0;
vertical-align: top;
}
.detail-table td.label {
width: 180px;
}
.name {
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<!-- <table class="detail-table">
<tr>
<td class="label">
<h4>Required Material</h4>
</td>
<td>SC Cal</td>
</tr>
<tr>
<td class="label">
<h4>Procedure</h4>
</td>
<td>
Checking Instrument Status, Running Callibartion
</td>
</tr>
<tr>
<td class="label">
<h4>Requirement</h4>
</td>
<td>
Deviation must be 2.0% ; 3 Impedance measurement must be OK; Measurement point must be within
range
</td>
</tr>
</table> -->
<h4>Required Material</h4>SC Cal
<h4>Procedure</h4>Checking Instrument Status, Running Callibartion
<h4>Requirement</h4>Deviation must be 2.0% ; 3 Impedance measurement must be OK; Measurement point must be within
<h4>Results</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Value</th>
<th>Range</th>
<th>Unit</th>
<th>Result</th>
</tr>
<tr>
<td class="param">Power +12V</td>
<td>11.79</td>
<td>11.00 - 14.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Power +24V</td>
<td>24.06</td>
<td>20.00 - 30.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Analog +12V</td>
<td>11.70</td>
<td>11.00 - 13.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Analog -12V</td>
<td>-11.72</td>
<td>-14.00 - -9.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Digital +56V</td>
<td>56.05</td>
<td>47.00 - 63.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">HGB Blank Voltage</td>
<td>4.21</td>
<td>3.85 - 4.85</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">FS Blank Voltage</td>
<td>0.29</td>
<td>0.07 - 1.00</td>
<td>V</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Laser Diode Current</td>
<td>28</td>
<td>20 - 70</td>
<td>mA</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Diluent Temperature</td>
<td>27</td>
<td>10.00 - 40.00</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Reagent preheating Temperature</td>
<td>42.2</td>
<td>39.5 - 44.0</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Optical System Temperature</td>
<td>29.4</td>
<td>15.0 - 40.0</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Liquid Pressure</td>
<td>92.0</td>
<td>70.00 - 110.0</td>
<td>kPa</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">Vacuum</td>
<td>-28.6</td>
<td>-35.0 - -26.0</td>
<td>kPa</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">WBC</td>
<td>99.93</td>
<td>75 - 125</td>
<td>%</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">RBC</td>
<td>101.49</td>
<td>75 - 125</td>
<td>%</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">HGB</td>
<td>99.65</td>
<td>75 - 125</td>
<td>%</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">MCV</td>
<td>99.94</td>
<td>75 - 125</td>
<td>%</td>
<td>Pass</td>
</tr>
<tr>
<td class="param">PLT</td>
<td>101.60</td>
<td>75 - 125</td>
<td>%</td>
<td>Pass</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
Instrument Auto Hematology Analyzer BC-5140 has been already calibrated. The result of calibration
is good.
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,418 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 1px 0;
padding: 0;
font-size: 13px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 1px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 10px;
margin-top: 10px;
}
.box h4 {
margin: 0;
}
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 1px 6px;
text-align: center;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.detail-table {
width: 100%;
border-collapse: collapse;
}
.detail-table td {
padding: 0;
vertical-align: top;
}
.detail-table td.label {
width: 180px;
}
.name {
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<table class="detail-table">
<tr>
<td class="label">
<h4>Required Material</h4>
</td>
<td>SC Cal</td>
</tr>
<tr>
<td class="label">
<h4>Procedure</h4>
</td>
<td>
Checking Instrument Status, Running Callibartion
</td>
</tr>
<tr>
<td class="label">
<h4>Requirement</h4>
</td>
<td>
Deviation must be 2.0% ; 3 Impedance measurement must be OK; Measurement point must be within range
</td>
</tr>
</table>
<h4>Results</h4>
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="50%" style="vertical-align:top; padding-right:10px;">
<h4>Calibration Factor</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Reference</th>
<th>Value</th>
<th>Result</th>
</tr>
<tr>
<td style="text-align:left;">WBC</td>
<td>75 - 125</td>
<td>95.20</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">RBC</td>
<td>75 - 125</td>
<td>105.38</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">HGB</td>
<td>75 - 125</td>
<td>101.86</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">MCV</td>
<td>75 - 125</td>
<td>104.22</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">PCT</td>
<td>75 - 125</td>
<td>105.58</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">RBC-O</td>
<td>75 - 125</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td style="text-align:left;">PCT-O</td>
<td>75 - 125</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td style="text-align:left;">PCT-H</td>
<td>75 - 125</td>
<td>-</td>
<td>-</td>
</tr>
</table>
</td>
<td width="50%" style="vertical-align:top; padding-left:10px;">
<h4>Optical</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Deviation</th>
<th>Result</th>
</tr>
<tr>
<td style="text-align:left;">DIFF_FS</td>
<td>0.1</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">DIFF_SS</td>
<td>0.8</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">DIFF_FC</td>
<td>0.5</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">DIFF_PMT</td>
<td>N/A</td>
<td>Pass</td>
</tr>
<tr>
<td style="text-align:left;">RET_FS</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td style="text-align:left;">RET_SS</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td style="text-align:left;">RET_FC</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td style="text-align:left;">RET_PMT</td>
<td>-</td>
<td>-</td>
</tr>
</table>
</td>
</tr>
</table>
<h4 style="margin-top:20px;">Impedance</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Target</th>
<th>1</th>
<th>2</th>
<th>3</th>
<th>Result</th>
</tr>
<tr>
<td style="text-align:left;">MCV_G</td>
<td>93.1</td>
<td>97.9</td>
<td>92.7</td>
<td>93.3</td>
<td>OK</td>
</tr>
<tr>
<td style="text-align:left;">HGB</td>
<td>4.40</td>
<td>4.75</td>
<td>4.40</td>
<td>4.40</td>
<td>OK</td>
</tr>
</table>
<h4 style="margin-top:20px;">ESR Measurement Point</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Tested</th>
<th>Reference</th>
<th>Result</th>
</tr>
<tr>
<td style="text-align:left;">Measurement Point (µL)</td>
<td>-</td>
<td>135 - 180</td>
<td>-</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
<h4>Instrument Auto Hematology Analyzer BC-760R has been already calibrated.
The result of calibration is good.</h4>
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,283 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.result-table td.param {
text-align: left;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 63%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4>
-
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength
<h4>Requirement</h4>
Expected Result : (-20) - (+20)
<h4>Result</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Value</th>
<th>Range</th>
<th>Unit</th>
<th>Result</th>
</tr>
<tr>
<td class='param'>Reaction Carousel Temperature</td>
<td>37.0</td>
<td>36.7 - 37.3</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Cuvette Cleaning Fluid Temperature</td>
<td>44.0</td>
<td>39.0 - 49.0</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Cuvette Wash Solution Temperature</td>
<td>44.2</td>
<td>39.0 - 49.00</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Cuvette Check</td>
<td>No Yellow Cuvette</td>
<td></td>
<td>N/A</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Photometer Check</td>
<td>7997</td>
<td>5000-8000</td>
<td>λ</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Bar Code Stability Check</td>
<td>Read</td>
<td>Read / No Read</td>
<td>N/A</td>
<td>Pass</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
Instrument BS-430 Chemistry Analyzer has been already calibrated.
The result of calibration is good.
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,306 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.result-table td.param {
text-align: left;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 63%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4>
Aquadibidestilata
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength
<br>
(340, 380, 405, 450, 505, 546, 570, 600, 660, 700, 750 and 800 nm)
<h4>Requirement</h4>
Expected Result : (-20) - (+20)
<h4>Result</h4>
<table class="result-table">
<tr>
<th>Parameters</th>
<th>Value</th>
<th>Range</th>
<th>Unit</th>
<th>Result</th>
</tr>
<tr>
<td class='param'>Incubation Module</td>
<td>37.0</td>
<td>36.7 - 37.3</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Reagent Compartment</td>
<td>5.0</td>
<td>2.0 - 8.0</td>
<td>°C</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Power 24V Voltage</td>
<td>23.94</td>
<td>20 - 30</td>
<td>Volt</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Power 12 V Voltage</td>
<td>11.87</td>
<td>11.0 - 14.0</td>
<td>Volt</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Vacuum Pressure Check</td>
<td>-23.00</td>
<td>-24.00 - -34.00</td>
<td>KPa</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>DCF Diagnosis</td>
<td>0.96</td>
<td>
< 1.5%</td> <td>%
</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Substrate Background</td>
<td>48</td>
<td>SD < 200</td> <td>N/A</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>System Repeatability</td>
<td>0.12%</td>
<td>CV 1.5%</td>
<td>%</td>
<td>Pass</td>
</tr>
<tr>
<td class='param'>Dark Current Count</td>
<td>80.2</td>
<td>0 - 350</td>
<td>N/A</td>
<td>Pass</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
Instrument Chemiluminescence Immunoassay System Mindray CL-900i have been already calibrated.
The result of calibration is good.
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,274 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4>
Standart Solution 1
<br>
Standart Solution 2
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength
<h4>Requirement</h4>
Expected Result :
<br>
Slope Na : (+40) - (+72) mV/dec
<br>
Slope K : (+40) - (+67) mV/dec
<br>
Slope Cl : (-25) - (-62) mV/dec
<h4>Result</h4>
<table class="result-table">
<tr>
<td>Type of Calibration</td>
<td>Slope Na</td>
<td>Status</td>
<td>Slope K</td>
<td>Status</td>
<td>Slope Cl</td>
<td>Status</td>
</tr>
<tr>
<td>Auto Calibration</td>
<td>(+46.4)</td>
<td>PASS</td>
<td>(+52.2)</td>
<td>PASS</td>
<td>(-41.0)</td>
<td>PASS</td>
</tr>
<tr>
<td>Manual Calibration</td>
<td>(+46.6)</td>
<td>PASS</td>
<td>(+51.7)</td>
<td>PASS</td>
<td>(-42.0)</td>
<td>PASS</td>
</tr>
<tr>
<td>Slope Wash Calibration</td>
<td>(+44.5)</td>
<td>PASS</td>
<td>(+50.9)</td>
<td>PASS</td>
<td>(-40.9)</td>
<td>PASS</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
Instrument JOKOH EX-D have been already calibrated.
The Result of Calibration is good.
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,302 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4>
Aquadibidestilata
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength
<br>
(340, 380, 405, 450, 505, 546, 570, 600, 660, 700, 750 and 800 nm)
<h4>Requirement</h4>
Expected Result : (-20) - (+20)
<h4>Result</h4>
<table class="result-table">
<tr>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
</tr>
<tr>
<td>340 nm</td>
<td>60</td>
<td>-2</td>
<td>PASS</td>
<td>570 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
</tr>
<tr>
<td>380 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
<td>600 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>405 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>660 nm</td>
<td>60</td>
<td>-2</td>
<td>PASS</td>
</tr>
<tr>
<td>450 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
<td>700 nm</td>
<td>60</td>
<td>-2</td>
<td>PASS</td>
</tr>
<tr>
<td>505 nm</td>
<td>60</td>
<td>-3</td>
<td>PASS</td>
<td>750 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
</tr>
<tr>
<td>546 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
<td>800 nm</td>
<td>60</td>
<td>-2</td>
<td>PASS</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
<h4>Instrument TMS 24i Premium have been already calibrated.
The Result of Calibration is good.</h4>
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,312 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td></td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya 60271
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4>
Aquadibidestilata
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength
<br>
(340, 380, 405, 450, 505, 546, 570, 600, 660, 700, 750 and 800 nm)
<h4>Requirement</h4>
Expected Result : (-20) - (+20)
<h4>Result</h4>
<table class="result-table">
<tr>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
</tr>
<tr>
<td>340 nm</td>
<td>60</td>
<td>1</td>
<td>PASS</td>
<td>570 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>380 nm</td>
<td>60</td>
<td>1</td>
<td>PASS</td>
<td>600 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>405 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>660 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>450 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>700 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>480 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>750 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>505 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>800 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
</tr>
<tr>
<td>546 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
<h4>Instrument TMS 30i have been already calibrated.
The Result of Calibration is good.</h4>
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,301 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Certificate of Instruments TMS50i</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..900;1,400..900&display=swap');
@page {
margin: 15mm;
}
body {
font-style: italic;
margin: 0;
padding: 0;
color: #000;
font-size: 13px;
}
.container {
width: 100%;
}
.doc-number {
font-style: normal;
padding: 0;
margin: 0;
text-align: right;
font-size: 12px;
}
.title {
margin: 30px 0px;
text-align: center;
font-style: italic;
text-decoration: underline;
font-size: 20px;
}
h4 {
margin: 0 0;
padding: 0;
font-size: 14px;
}
.customer-table {
width: 100%;
border-collapse: collapse;
}
.customer-table td {
padding: 3px 0;
vertical-align: top;
}
.customer-table td.label {
width: 180px;
}
.box {
border: 1px solid #000;
padding: 12px;
margin-top: 20px;
}
/* .box h4 {
margin: 0;
margin-top
} */
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
font-size: 13px;
}
.result-table th,
.result-table td {
border: 1px solid #000000;
padding: 5px 6px;
text-align: center;
}
.conclusion {
margin-top: 15px;
}
.footer {
margin-top: 20px;
width: 250px;
}
.date {
margin-bottom: 70px;
font-style: italic;
}
.name {
/* font-weight: bold; */
font-style: italic;
border-bottom: 1px solid #000;
display: inline-block;
width: 80%;
padding-bottom: 2px;
}
.position {
margin-top: 5px;
font-style: italic;
}
/* Bersihkan float agar elemen setelahnya tidak berantakan */
.clearfix::after {
content: "";
clear: both;
display: table;
}
</style>
</head>
<body>
<div class="container">
<div class="doc-number">
Nomor: FO.III.12/04.00/2019
</div>
<div class="title">
<h3>Certificate of Instrument Calibration</h3>
</div>
<div class="section">
<table class="customer-table">
<tr>
<td class="label">
<h4>Customer Data</h4>
</td>
<td>
</td>
</tr>
<tr>
<td class="label">
Laboratory / Hospital
</td>
<td>
: Trisensa Diagnostic Center
</td>
</tr>
<tr>
<td class="label">
Address
</td>
<td>
: Jl. Taman AIS Yasin No.5, Embong Kaliasin, Kec. Genteng, Surabaya
</td>
</tr>
<tr>
<td class="label">
Instrument
</td>
<td>
: Clinical Chemistry Analyzer TMS 50i Superior
</td>
</tr>
<tr>
<td class="label">
Serial Number
</td>
<td>
: 5303150816
</td>
</tr>
<tr>
<td class="label">
Date of Calibration
</td>
<td>
: January 09, 2026
</td>
</tr>
<tr>
<td class="label">
Valid Until
</td>
<td>
: January 09, 2027
</td>
</tr>
</table>
</div>
<div class="box">
<h4>Required Material</h4> Aquadibidestilata
<h4>Procedure</h4>
Running 60 samples (Aquadibidestilata) for 12 Wavelength (340, 380, 405, 450, 505, 546, 570, 600, 660, 700, 750 and 800 nm)
<h4>Requirement</h4>
Expected Result : (-20) - (+20)
<h4>Result</h4>
<table class="result-table">
<tr>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
<td>Wave Length</td>
<td>Number of Run</td>
<td>Result</td>
<td>Status</td>
</tr>
<tr>
<td>340 nm</td>
<td>60</td>
<td>-2</td>
<td>PASS</td>
<td>570 nm</td>
<td>60</td>
<td>1</td>
<td>PASS</td>
</tr>
<tr>
<td>380 nm</td>
<td>60</td>
<td>-1</td>
<td>PASS</td>
<td>600 nm</td>
<td>60</td>
<td>2</td>
<td>PASS</td>
</tr>
<tr>
<td>405 nm</td>
<td>60</td>
<td>0</td>
<td>PASS</td>
<td>660 nm</td>
<td>60</td>
<td>3</td>
<td>PASS</td>
</tr>
<tr>
<td>450 nm</td>
<td>60</td>
<td>1</td>
<td>PASS</td>
<td>700 nm</td>
<td>60</td>
<td>2</td>
<td>PASS</td>
</tr>
<tr>
<td>505 nm</td>
<td>60</td>
<td>2</td>
<td>PASS</td>
<td>750 nm</td>
<td>60</td>
<td>2</td>
<td>PASS</td>
</tr>
<tr>
<td>546 nm</td>
<td>60</td>
<td>1</td>
<td>PASS</td>
<td>800 nm</td>
<td>60</td>
<td>2</td>
<td>PASS</td>
</tr>
</table>
<div class="conclusion">
<h4>Conclusion</h4>
<h4>Instrument TMS 50i Superior have been already calibrated.
The Result of Calibration is good.</h4>
</div>
</div>
<div class="clearfix">
<div class="footer">
<div class="date">Jakarta, January 23, 2026</div>
<div class="name">Adhitya Pranata Putra</div>
<div class="position">Technical Support Manager</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,183 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Maintenance Certificate - <?= $certificate['certname'] ?></title>
<style>
@page {
margin: 0;
padding: 0;
}
body {
font-family: Arial;
margin: 0;
padding: 0;
/* font-size: 12px; */
/* line-height: 1.4; */
color: #000000;
width: 100%;
height: 100%;
}
/* Container untuk background agar memenuhi halaman */
.bg-container {
margin:0;
padding:0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1000;
}
.bg-container img {
margin:0;
padding:0;
width: 100%;
height: 100%;
}
h1 {
margin :0;
padding:0;
color:#336600;
}
.container {
max-width: 100%;
margin: 0;
/* padding-top: 20px; */
}
.instument-name {
text-align: center;
margin: 0;
padding: 0;
margin-top: 230px;
margin-bottom: 25px;
}
.site-name {
text-align: center;
margin-bottom: 40px;
}
.detail-information {
text-align: center;
margin-bottom: 137px;
}
h4 {
margin :0;
padding:0;
/* color:#336600; */
}
/* Menggunakan table agar dompdf tidak bingung */
.signature-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 0px;
}
.signature-table td {
width: 50%; /* Membagi dua sisi sama rata */
text-align: center;
vertical-align: top;
}
.name {
font-weight: bold;
text-decoration: underline;
display: block;
margin-bottom: 1px;
}
.position {
font-weight: bold;
display: block;
}
.fo-wrapper {
margin-left: 40px;
}
</style>
</head>
<body>
<div class="bg-container">
<img src="<?=base_url();?>/assets/images/background_certificate/maintenance.jpeg">
</div>
<div class="container">
<div class="instument-name">
<h1> &lt;&lt;Nama Alat&gt;&gt; </h1>
</div>
<div class="site-name">
<h1> at &lt;&lt;Nama Rumah Sakit / Laboratorium - Kota&gt;&gt; </h1>
</div>
<div class="detail-information">
<h4>Serial Number: &lt;&lt;Serial Number&gt;&gt;</h4>
<h4>has completed through a series of &lt;&lt;Jenis Sertifikat&gt;&gt;</h4>
<h4>and the final result:</h4>
<h2>PASSED</h2>
<h4>Date of &lt;&lt;Jenis Sertifikat&gt;&gt; and Inspection: &lt;&lt;Tanggal Terbit&gt;&gt;</h4>
<h4>&lt;&lt;Valid&gt;&gt; &lt;&lt;Tanggal Berakhir&gt;&gt;</h4>
</div>
<table class="signature-table">
<tr>
<td>
<span class="name">Adhitya Pranata Putra</span>
<span class="position">Technical Support Manager</span>
</td>
<td>
<span class="name">&lt;&lt;Nama TSO&gt;&gt;</span>
<span class="position">&lt;&lt;Jabatan&gt;&gt;</span>
</td>
</tr>
</table>
<div class="fo-wrapper">
<p>&lt;&lt;FO&gt;&gt;</p>
</div>
</div>
<div class="container">
<div class="instument-name">
<h1> &lt;&lt;Nama Alat&gt;&gt; </h1>
</div>
<div class="site-name">
<h1> at &lt;&lt;Nama Rumah Sakit / Laboratorium - Kota&gt;&gt; </h1>
</div>
<div class="detail-information">
<h4>Serial Number: &lt;&lt;Serial Number&gt;&gt;</h4>
<h4>has completed through a series of &lt;&lt;Jenis Sertifikat&gt;&gt;</h4>
<h4>and the final result:</h4>
<h2>PASSED</h2>
<h4>Date of &lt;&lt;Jenis Sertifikat&gt;&gt; and Inspection: &lt;&lt;Tanggal Terbit&gt;&gt;</h4>
<h4>&lt;&lt;Valid&gt;&gt; &lt;&lt;Tanggal Berakhir&gt;&gt;</h4>
</div>
<table class="signature-table">
<tr>
<td>
<span class="name">Adhitya Pranata Putra</span>
<span class="position">Technical Support Manager</span>
</td>
<td>
<span class="name">&lt;&lt;Nama TSO&gt;&gt;</span>
<span class="position">&lt;&lt;Jabatan&gt;&gt;</span>
</td>
</tr>
</table>
<div class="fo-wrapper">
<p>&lt;&lt;FO&gt;&gt;</p>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,545 @@
<?= $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() ?>

View File

@ -0,0 +1,150 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Maintenance Certificate - <?= $certificate['certname'] ?></title>
<style>
@page {
margin: 0;
padding: 0;
}
body {
font-family: Arial;
margin: 0;
padding: 0;
/* font-size: 12px; */
/* line-height: 1.4; */
color: #000000;
width: 100%;
height: 100%;
}
/* Container untuk background agar memenuhi halaman */
.bg-container {
margin:0;
padding:0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1000;
}
.bg-container img {
margin:0;
padding:0;
width: 100%;
height: 100%;
}
h1 {
margin :0;
padding:0;
color:#336600;
}
.container {
max-width: 100%;
margin: 0;
/* padding-top: 20px; */
}
.instument-name {
text-align: center;
margin: 0;
padding: 0;
margin-top: 230px;
margin-bottom: 25px;
}
.site-name {
text-align: center;
margin-bottom: 55px;
}
.detail-information {
text-align: center;
margin-bottom: 67px;
}
h4 {
margin :0;
padding:0;
/* color:#336600; */
}
/* Menggunakan table agar dompdf tidak bingung */
.signature-table {
width: 100%;
border-collapse: collapse;
margin-left: 17%;
margin-bottom: 0px;
}
.signature-table td {
width: 50%; /* Membagi dua sisi sama rata */
text-align: left;
vertical-align: top;
}
.name {
font-weight: bold;
text-decoration: underline;
display: block;
margin-bottom: 1px;
}
.position {
font-weight: bold;
display: block;
}
.fo-wrapper {
margin-left: 40px;
}
</style>
</head>
<body>
<div class="bg-container">
<img src="<?=base_url();?>/assets/images/background_certificate/maintenance.jpeg">
</div>
<div class="container">
<div class="instument-name">
<h1> &lt;&lt;Nama Analis&gt;&gt; </h1>
</div>
<div class="site-name">
<h1> at &lt;&lt;Nama Rumah Sakit / Laboratorium - Kota&gt;&gt; </h1>
</div>
<div class="detail-information">
<h4>In Recording of Participation and Successful</h4>
<h4>Completion of Mindray Hematology Analyzer Training</h4>
<h2>BC5140</h2>
<h3>Date : February 05, 2026</h3>
</div>
<table class="signature-table">
<tr>
<td>
<span class="name"><br></span>
<span class="name"><br></span>
<span class="name"><br></span>
<span class="name"><br></span>
<span class="name">Adhitya Pranata Putra</span>
<span class="position">Technical Support Manager</span>
</td>
<td>
<span class="position">Trainer,</span>
<span class="name"><br></span>
<span class="name"><br></span>
<span class="name"><br></span>
<span class="name">&lt;&lt;Nama TSO&gt;&gt;</span>
<span class="position">&lt;&lt;Jabatan&gt;&gt;</span>
</td>
</tr>
</table>
<div class="fo-wrapper">
<p>&lt;&lt;FO&gt;&gt;</p>
</div>
</div>
</body>
</html>

View File

@ -212,16 +212,25 @@
<li><a href="<?=base_url();?>invtrans/user/<?=$_SESSION['userid'];?>">Transactions</a></li> <li><a href="<?=base_url();?>invtrans/user/<?=$_SESSION['userid'];?>">Transactions</a></li>
</ul> </ul>
</li> </li>
<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">All</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/maintenance">Maintenance</a></li>
</ul>
</li>
<!-- <li> <a class="waves-effect waves-dark" href='<?=base_url();?>certificates' aria-expanded="false"> <i class="fa-solid fa-certificate"></i><span class='hide-menu'>Certificate</span> </a> </li> -->
<li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-bug"></i><span class='hide-menu'>Bug N Feature</span> </a> <li> <a class="has-arrow waves-effect waves-dark" href='javascript:void(0)' aria-expanded="false"> <i class="fa-solid fa-bug"></i><span class='hide-menu'>Bug N Feature</span> </a>
<ul aria-expanded="false" class="collapse"> <ul aria-expanded="false" class="collapse">
<li><a href="<?=base_url();?>bugs">Bug List</a></li> <li><a href="<?=base_url();?>bugs">Bug List</a></li>
<li><a href="<?=base_url();?>bugs/count">Bug Count</a></li> <li><a href="<?=base_url();?>bugs/count">Bug Count</a></li>
</ul> </ul>
</li>
<li> <a class="waves-effect waves-dark" href='<?=base_url();?>guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li> <li> <a class="waves-effect waves-dark" href='<?=base_url();?>guidebook' aria-expanded="false"> <i class="fa-solid fa-book"></i><span class='hide-menu'>Guidebook</span> </a> </li>
<li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li> <li> <a class="waves-effect waves-dark" href='https://clqms.services-summit.my.id/' aria-expanded="false"> <i class="fa-solid fa-microscope"></i><span class='hide-menu'>CLQMS</span> </a> </li>
<?php
} <?php } ?>
?>
</ul> </ul>
</nav> </nav>
</div> </div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB