aplikasi-it/index.html
2026-04-08 10:47:36 +07:00

433 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<base href=""/>
<title>Aplikasi RSAB Harapan Kita</title>
<meta property="og:type" content="article" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" />
<link rel="shortcut icon" href="assets/img/favicon.png" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700" />
<link href="metronic/assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css" />
<link href="metronic/assets/css/style.bundle.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" integrity="sha512-2SwdPD6INVrV/lHTZbO2nodKhrnDdJK9/kg2XD1r9uGqPo1cUbujc+IYdlYdEErWNu69gVcYgdxlmVmzTWnetw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script>
if (window.top != window.self) {
window.top.location.replace(window.self.location.href);
}
</script>
<style>
.app-card {
position: relative;
transition: transform .2s ease, box-shadow .2s ease;
cursor: pointer;
}
.app-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 30px rgba(59, 130, 246, 0.15);
}
.app-thumb {
height: 200px;
width: auto;
max-width: 100%;
object-fit: contain;
display: block;
margin: 0 auto;
}
.app-placeholder {
width: 100%;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: rgba(255,255,255,0.9);
border-radius: .5rem;
}
.app-title {
color: #0f172a;
font-weight: 700;
font-size: 1rem;
line-height: 1.3;
margin: 1rem 0 0 0;
}
.app-juknis-btn {
position: absolute;
right: 1rem;
bottom: 1rem;
z-index: 2;
}
.btn-juknis {
width: 44px;
height: 44px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
background: rgba(255,255,255,.95);
border: none;
box-shadow: 0 4px 12px rgba(0,0,0,.25);
transition: all .2s ease;
color: #3b82f6;
font-size: 1.1rem;
cursor: pointer;
}
.btn-juknis:hover {
background: #3b82f6;
color: #fff;
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
}
.search-section {
background: #fff;
border-radius: 1rem;
padding: 1.5rem;
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
}
.search-input-group {
max-width: 600px;
margin: 0 auto;
}
.pagination-sm .page-link {
border-radius: .375rem;
margin: 0 .15rem;
}
.pagination-sm .page-item.active .page-link {
background-color: #3b82f6;
border-color: #3b82f6;
}
</style>
</head>
<body id="kt_body">
<script>
var defaultThemeMode = "light";
var themeMode;
if (document.documentElement) {
if (document.documentElement.hasAttribute("data-bs-theme-mode")) {
themeMode = document.documentElement.getAttribute("data-bs-theme-mode");
} else {
if (localStorage.getItem("data-bs-theme") !== null) {
themeMode = localStorage.getItem("data-bs-theme");
} else {
themeMode = defaultThemeMode;
}
}
if (themeMode === "system") {
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
document.documentElement.setAttribute("data-bs-theme", themeMode);
}
</script>
<div class="d-flex flex-column flex-root">
<div class="bg-light py-4">
<div class="container-xxl">
<div class="text-center mb-4">
<div class="d-flex justify-content-center align-items-center gap-2 mb-2">
<img src="assets/img/favicon.png" alt="Logo" style="height:36px;">
<div class="fs-4 fw-bold text-dark">INSTALASI <span class="text-primary">SIMRS</span></div>
</div>
<div class="fw-semibold text-muted">Aplikasi penunjang pelayanan dan unit RS</div>
</div>
<div class="search-section mb-4">
<div class="search-input-group">
<div class="input-group">
<span class="input-group-text bg-white border-end-0">
<i class="fa fa-search text-primary"></i>
</span>
<input id="searchInput"
type="text"
class="form-control border-start-0"
placeholder="Cari aplikasi atau kata kunci...">
</div>
<small class="text-muted d-block mt-2 text-center">
Pencarian langsung, hasil diperbarui otomatis
</small>
</div>
</div>
<div id="appListContainer" class="row g-4"></div>
<div class="d-flex justify-content-between align-items-center mt-4 flex-wrap gap-3">
<div id="paginationInfo" class="text-muted small"></div>
<div id="paginationContainer"></div>
</div>
<div class="text-center text-muted small mt-4">
Created by SIMRS &copy; 2026. All rights reserved.
</div>
</div>
</div>
</div>
<script>var hostUrl = "assets/";</script>
<script src="metronic/assets/plugins/global/plugins.bundle.js"></script>
<script src="metronic/assets/js/scripts.bundle.js"></script>
<script src="metronic/assets/plugins/custom/fullcalendar/fullcalendar.bundle.js"></script>
<script src="metronic/assets/plugins/custom/datatables/datatables.bundle.js"></script>
<script src="metronic/assets/js/widgets.bundle.js"></script>
<script src="metronic/assets/js/custom/widgets.js"></script>
<script src="metronic/assets/js/custom/apps/chat/chat.js"></script>
<script src="metronic/assets/js/custom/utilities/modals/users-search.js"></script>
<script src="metronic/assets/plugins/custom/typedjs/typedjs.bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/js/all.min.js" integrity="sha512-6BTOlkauINO65nLhXhthZMtepgJSghyimIalb+crKRPhvhmsCdnIuGcVbR5/aQY2A+260iC1OPy1oCdB6pSSwQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
if (typeof toastr !== "undefined") {
toastr.options = {
"closeButton": false,
"debug": false,
"newestOnTop": false,
"progressBar": false,
"positionClass": "toastr-top-right",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
};
}
</script>
<script>
$(document).ready(function () {
let currentPage = 1;
let currentSearch = '';
let searchTimer = null;
function esc(str) {
return String(str ?? '')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
function isAbsoluteUrl(url) {
return /^https?:\/\//i.test(url || '');
}
function buildLink(itemUrl) {
if (!itemUrl) return '#';
if (isAbsoluteUrl(itemUrl)) return itemUrl;
itemUrl = String(itemUrl).replace(/^\/+/, '');
return `preview-dokumen/${itemUrl}`;
}
function renderCard(item) {
const name = esc(item.nama_aplikasi ?? 'Aplikasi');
const link = buildLink(item.url);
let urlJuknis= item.file_juknis_url || '';
let result = urlJuknis.includes('preview-dokumen/')
? urlJuknis.split('preview-dokumen/')[1]
: '';
const imageContent = item.image_url
? `<img src="${esc(item.image_url)}" class="app-thumb" alt="${name}">`
: `<div class="app-placeholder">
<div class="text-center px-3">
<i class="fa fa-image fa-3x mb-2 opacity-75"></i>
<div class="fw-semibold">Tidak ada gambar</div>
</div>
</div>`;
const juknisBtn = item.file_juknis_url
? `<div class="app-juknis-btn">
<button type="button"
class="btn-juknis bg-primary border-0"
title="Download Juknis"
data-juknis="https://permintaan-it.rsabhk.co.id/preview-dokumen/${result}">
<i class="fa-solid fa-download text-white"></i>
</button>
</div>`
: '';
return `
<div class="col-12 col-sm-6 col-lg-4 col-xl-3">
<div class="app-card border border-gray-500 border-active active rounded p-10 border-3 hover-elevate-up"
data-link="${esc(link)}">
<div class="text-center">
${imageContent}
<h5 class="app-title">${name}</h5>
<small class="text-muted">Klik di sini untuk mengakses laman</small>
</div>
${juknisBtn}
</div>
</div>
`;
}
function renderInfo(meta) {
if (!meta || meta.total === 0) {
$('#paginationInfo').text('');
return;
}
$('#paginationInfo').text(`Menampilkan ${meta.from}-${meta.to} dari ${meta.total} data`);
}
function renderPagination(meta) {
const container = $('#paginationContainer');
container.empty();
if (!meta || meta.last_page <= 1) return;
const current = meta.current_page;
const last = meta.last_page;
const win = 2;
let start = Math.max(1, current - win);
let end = Math.min(last, current + win);
if (current <= 2) end = Math.min(last, 1 + win * 2 + 1);
if (current >= last - 1) start = Math.max(1, last - (win * 2) - 1);
let html = `<ul class="pagination pagination-sm mb-0">`;
html += `
<li class="page-item ${current <= 1 ? 'disabled' : ''}">
<a class="page-link page-nav" href="#" data-page="${current - 1}">&laquo;</a>
</li>`;
if (start > 1) {
html += `<li class="page-item"><a class="page-link page-nav" href="#" data-page="1">1</a></li>`;
if (start > 2) html += `<li class="page-item disabled"><span class="page-link">…</span></li>`;
}
for (let i = start; i <= end; i++) {
html += `
<li class="page-item ${i === current ? 'active' : ''}">
<a class="page-link page-nav" href="#" data-page="${i}">${i}</a>
</li>`;
}
if (end < last) {
if (end < last - 1) html += `<li class="page-item disabled"><span class="page-link">…</span></li>`;
html += `<li class="page-item"><a class="page-link page-nav" href="#" data-page="${last}">${last}</a></li>`;
}
html += `
<li class="page-item ${current >= last ? 'disabled' : ''}">
<a class="page-link page-nav" href="#" data-page="${current + 1}">&raquo;</a>
</li>`;
html += `</ul>`;
container.html(html);
}
function loadAplikasi() {
$.ajax({
url: 'proxy.php',
type: 'GET',
data: { search: currentSearch, page: currentPage },
success: function (res) {
const container = $('#appListContainer');
container.empty();
if (!res || !res.status) {
container.html(`
<div class="col-12">
<div class="alert alert-danger text-center mb-0">
<i class="fa fa-exclamation-circle me-2"></i>Response tidak valid
</div>
</div>`);
$('#paginationInfo').text('');
$('#paginationContainer').empty();
return;
}
if (!res.data || res.data.length === 0) {
const message = currentSearch
? `Tidak ditemukan hasil untuk "<strong>${esc(currentSearch)}</strong>"`
: 'Belum ada data aplikasi';
container.html(`
<div class="col-12">
<div class="alert alert-secondary text-center mb-0">
<i class="fa fa-info-circle me-2"></i>${message}
</div>
</div>`);
} else {
res.data.forEach(item => container.append(renderCard(item)));
}
renderInfo(res.meta);
renderPagination(res.meta);
},
error: function () {
$('#appListContainer').html(`
<div class="col-12">
<div class="alert alert-danger text-center mb-0">
<i class="fa fa-times-circle me-2"></i> Gagal mengambil data aplikasi
</div>
</div>`);
$('#paginationInfo').text('');
$('#paginationContainer').empty();
}
});
}
$(document).on('click', '.page-nav', function (e) {
e.preventDefault();
const page = parseInt($(this).data('page'), 10);
if (!page || page < 1) return;
if ($(this).closest('.page-item').hasClass('disabled') ||
$(this).closest('.page-item').hasClass('active')) return;
currentPage = page;
loadAplikasi();
$('html, body').animate({ scrollTop: 0 }, 300);
});
$(document).on('click', '.btn-juknis', function (e) {
e.preventDefault();
e.stopPropagation();
const url = $(this).data('juknis');
if (url) {
const link = document.createElement('a');
link.href = url;
link.download = '';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
$(document).on('click', '.app-card', function () {
const link = $(this).data('link');
if (!link || link === '#') return;
window.open(link, '_blank');
});
$('#searchInput').on('input', function () {
const value = $(this).val().trim();
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
currentSearch = value;
currentPage = 1;
loadAplikasi();
}, 350);
});
loadAplikasi();
});
</script>
</body>
</html>