forked from mahdahar/crm-summit
Update Certificare V1
This commit is contained in:
parent
d765b82c16
commit
1328fed57b
@ -206,6 +206,27 @@ $routes->match(['get', 'post'], '/guidebook/edit/(:any)', 'Guidebook::edit/$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
|
||||
$routes->get('/mailgroups', 'Mailgroups::index');
|
||||
|
||||
1156
app/Controllers/Certificates.php
Normal file
1156
app/Controllers/Certificates.php
Normal file
File diff suppressed because it is too large
Load Diff
655
app/Views/certificate_calibration_index.php
Normal file
655
app/Views/certificate_calibration_index.php
Normal 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> 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() ?>
|
||||
577
app/Views/certificate_index.php
Normal file
577
app/Views/certificate_index.php
Normal 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() ?>
|
||||
361
app/Views/certificate_maintenance_index.php
Normal file
361
app/Views/certificate_maintenance_index.php
Normal 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> 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() ?>
|
||||
361
app/Views/certificate_training_index.php
Normal file
361
app/Views/certificate_training_index.php
Normal 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> 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() ?>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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>
|
||||
183
app/Views/certificates/certificate_maintenance.php
Normal file
183
app/Views/certificates/certificate_maintenance.php
Normal 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> <<Nama Alat>> </h1>
|
||||
</div>
|
||||
|
||||
<div class="site-name">
|
||||
<h1> at <<Nama Rumah Sakit / Laboratorium - Kota>> </h1>
|
||||
</div>
|
||||
|
||||
<div class="detail-information">
|
||||
<h4>Serial Number: <<Serial Number>></h4>
|
||||
|
||||
<h4>has completed through a series of <<Jenis Sertifikat>></h4>
|
||||
<h4>and the final result:</h4>
|
||||
<h2>PASSED</h2>
|
||||
<h4>Date of <<Jenis Sertifikat>> and Inspection: <<Tanggal Terbit>></h4>
|
||||
<h4><<Valid>> <<Tanggal Berakhir>></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"><<Nama TSO>></span>
|
||||
<span class="position"><<Jabatan>></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="fo-wrapper">
|
||||
<p><<FO>></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="instument-name">
|
||||
<h1> <<Nama Alat>> </h1>
|
||||
</div>
|
||||
|
||||
<div class="site-name">
|
||||
<h1> at <<Nama Rumah Sakit / Laboratorium - Kota>> </h1>
|
||||
</div>
|
||||
|
||||
<div class="detail-information">
|
||||
<h4>Serial Number: <<Serial Number>></h4>
|
||||
|
||||
<h4>has completed through a series of <<Jenis Sertifikat>></h4>
|
||||
<h4>and the final result:</h4>
|
||||
<h2>PASSED</h2>
|
||||
<h4>Date of <<Jenis Sertifikat>> and Inspection: <<Tanggal Terbit>></h4>
|
||||
<h4><<Valid>> <<Tanggal Berakhir>></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"><<Nama TSO>></span>
|
||||
<span class="position"><<Jabatan>></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="fo-wrapper">
|
||||
<p><<FO>></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
545
app/Views/certificates/certificate_maintenance_index.php
Normal file
545
app/Views/certificates/certificate_maintenance_index.php
Normal 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() ?>
|
||||
150
app/Views/certificates/certificate_training.php
Normal file
150
app/Views/certificates/certificate_training.php
Normal 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> <<Nama Analis>> </h1>
|
||||
</div>
|
||||
|
||||
<div class="site-name">
|
||||
<h1> at <<Nama Rumah Sakit / Laboratorium - Kota>> </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"><<Nama TSO>></span>
|
||||
<span class="position"><<Jabatan>></span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="fo-wrapper">
|
||||
<p><<FO>></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -212,16 +212,25 @@
|
||||
<li><a href="<?=base_url();?>invtrans/user/<?=$_SESSION['userid'];?>">Transactions</a></li>
|
||||
</ul>
|
||||
</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>
|
||||
<ul aria-expanded="false" class="collapse">
|
||||
<li><a href="<?=base_url();?>bugs">Bug List</a></li>
|
||||
<li><a href="<?=base_url();?>bugs/count">Bug Count</a></li>
|
||||
</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='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>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
BIN
public/assets/images/background_certificate/maintenance.jpeg
Normal file
BIN
public/assets/images/background_certificate/maintenance.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 93 KiB |
Loading…
x
Reference in New Issue
Block a user