3708 lines
105 KiB
PHP
3708 lines
105 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="id">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Data Pasien - Sistem TBC</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
|
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<script src="https://unpkg.com/lucide@latest"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
font-family: 'Poppins', sans-serif;
|
|
}
|
|
|
|
body {
|
|
display: flex;
|
|
background: #f5f6fa;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* SIDEBAR */
|
|
.sidebar {
|
|
width: 250px;
|
|
height: 100vh;
|
|
background: #c40000;
|
|
padding-top: 30px;
|
|
position: fixed;
|
|
z-index: 100;
|
|
}
|
|
|
|
.sidebar h2 {
|
|
color: white;
|
|
text-align: center;
|
|
margin-bottom: 40px;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.menu {
|
|
list-style: none;
|
|
}
|
|
|
|
.menu a {
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 15px 25px;
|
|
color: white;
|
|
transition: 0.3s;
|
|
gap: 15px;
|
|
}
|
|
|
|
.menu li:hover a,
|
|
.menu li.active a {
|
|
background: white;
|
|
color: #c40000;
|
|
border-radius: 30px 0 0 30px;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
/* CONTENT */
|
|
.main-content {
|
|
margin-left: 250px;
|
|
padding: 40px;
|
|
width: calc(100% - 250px);
|
|
}
|
|
|
|
.header-wrapper {
|
|
border-bottom: 1px solid #e0e0e0;
|
|
margin-bottom: 30px;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.header-title {
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
color: #c40000;
|
|
display: inline-block;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.top-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.action-header-left {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
.btn-tambah {
|
|
background: #c40000;
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border-radius: 10px;
|
|
border: none;
|
|
font-weight: 600;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
cursor: pointer;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
/* Accordion Filter Styles */
|
|
.filter-accordion {
|
|
background: white;
|
|
border-radius: 15px;
|
|
margin-bottom: 25px;
|
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
|
overflow: hidden;
|
|
border: 1px solid #eee;
|
|
}
|
|
|
|
.filter-header {
|
|
padding: 15px 25px;
|
|
background: #fff;
|
|
cursor: pointer;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
.filter-header:hover {
|
|
background: #fefefe;
|
|
}
|
|
|
|
.filter-header h4 {
|
|
font-size: 15px;
|
|
color: #333;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.filter-content {
|
|
padding: 0 25px;
|
|
max-height: 0;
|
|
overflow: hidden;
|
|
transition: max-height 0.3s ease-out, padding 0.3s ease;
|
|
background: #fff;
|
|
}
|
|
|
|
.filter-content.active {
|
|
padding: 20px 25px;
|
|
max-height: 500px;
|
|
border-top: 1px solid #f5f5f5;
|
|
}
|
|
|
|
.filter-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 15px;
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.filter-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.filter-group label {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #64748b;
|
|
}
|
|
|
|
.filter-group input,
|
|
.filter-group select {
|
|
padding: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8px;
|
|
outline: none;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.filter-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 10px;
|
|
margin-top: 15px;
|
|
border-top: 1px dashed #eee;
|
|
padding-top: 15px;
|
|
}
|
|
|
|
.btn-cari {
|
|
background: #c40000;
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border-radius: 8px;
|
|
border: none;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.btn-export {
|
|
background: #27ae60;
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border-radius: 8px;
|
|
border: none;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.btn-reset {
|
|
background: #64748b;
|
|
color: white;
|
|
padding: 10px 20px;
|
|
border-radius: 8px;
|
|
border: none;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.search-wrapper {
|
|
position: relative;
|
|
width: 300px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.search-wrapper .icon-container {
|
|
position: absolute;
|
|
left: 15px;
|
|
display: flex;
|
|
align-items: center;
|
|
pointer-events: none;
|
|
z-index: 9;
|
|
color: #888;
|
|
}
|
|
|
|
.search-wrapper input {
|
|
width: 100%;
|
|
padding: 12px 15px 12px 45px !important;
|
|
border-radius: 12px;
|
|
border: 1px solid #ddd;
|
|
background: #fff;
|
|
outline: none;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.table-container {
|
|
background: white;
|
|
border-radius: 20px;
|
|
padding: 20px;
|
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
|
|
width: 100%;
|
|
}
|
|
|
|
/* WRAPPER SCROLL */
|
|
.table-scroll {
|
|
width: 100%;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
padding: 14px 12px;
|
|
text-align: left;
|
|
vertical-align: middle;
|
|
font-size: 13px;
|
|
word-break: break-word;
|
|
}
|
|
|
|
th {
|
|
background-color: #fcfcfc;
|
|
color: #333;
|
|
font-weight: 600;
|
|
border-bottom: 2px solid #f0f0f0;
|
|
}
|
|
|
|
td {
|
|
border-bottom: 1px solid #eee;
|
|
color: #555;
|
|
background: white;
|
|
}
|
|
|
|
.col-no {
|
|
width: 5%;
|
|
text-align: center;
|
|
}
|
|
|
|
.col-nama {
|
|
width: 18%;
|
|
}
|
|
|
|
.col-nik {
|
|
width: 12%;
|
|
}
|
|
|
|
.col-tgl {
|
|
width: 10%;
|
|
}
|
|
|
|
.col-jk {
|
|
width: 5%;
|
|
text-align: center;
|
|
}
|
|
|
|
.col-alamat {
|
|
width: 20%;
|
|
}
|
|
|
|
.col-telp {
|
|
width: 10%;
|
|
}
|
|
|
|
.col-email {
|
|
width: 12%;
|
|
}
|
|
|
|
.col-status {
|
|
width: 10%;
|
|
}
|
|
|
|
.col-aksi {
|
|
width: 8%;
|
|
text-align: center;
|
|
}
|
|
|
|
/* KOLOM FILE */
|
|
.col-file {
|
|
min-width: 160px;
|
|
text-align: center;
|
|
}
|
|
|
|
.status-select {
|
|
padding: 8px 12px;
|
|
border-radius: 8px;
|
|
border: 1px solid #e2e8f0;
|
|
background: #f8fafc;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #475569;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
}
|
|
|
|
/* ICON DENGAN BACKGROUND (MODERN) */
|
|
.action-btns {
|
|
display: flex;
|
|
gap: 8px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.btn-icon {
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
.btn-icon.info {
|
|
background: #e8f5e9;
|
|
color: #2e7d32;
|
|
}
|
|
|
|
.btn-icon.info:hover {
|
|
background: #2e7d32;
|
|
color: white;
|
|
}
|
|
|
|
.btn-icon.edit {
|
|
background: #e3f2fd;
|
|
color: #1565c0;
|
|
}
|
|
|
|
.btn-icon.edit:hover {
|
|
background: #1565c0;
|
|
color: white;
|
|
}
|
|
|
|
.btn-icon.trash {
|
|
background: #ffebee;
|
|
color: #c62828;
|
|
}
|
|
|
|
.btn-icon.trash:hover {
|
|
background: #c62828;
|
|
color: white;
|
|
}
|
|
|
|
.pagination-wrapper {
|
|
margin-top: 30px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 10px 20px;
|
|
background: #f8fafc;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.pagination-wrapper .text-muted {
|
|
font-size: 14px;
|
|
color: #64748b !important;
|
|
}
|
|
|
|
.pagination {
|
|
display: flex;
|
|
list-style: none;
|
|
gap: 8px;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.page-link {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 40px;
|
|
height: 40px;
|
|
padding: 0 14px;
|
|
border-radius: 10px;
|
|
background: white;
|
|
border: 1px solid #e2e8f0;
|
|
color: #475569;
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.page-link:hover {
|
|
background: #fff1f1;
|
|
border-color: #c40000;
|
|
color: #c40000;
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.page-item.active .page-link {
|
|
background: #c40000;
|
|
border-color: #c40000;
|
|
color: white;
|
|
box-shadow: 0 4px 12px rgba(196, 0, 0, 0.25);
|
|
}
|
|
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.4);
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.modal-content {
|
|
background: white;
|
|
padding: 30px;
|
|
border-radius: 20px;
|
|
width: 650px;
|
|
max-height: 90vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.modal-card {
|
|
background: #fff;
|
|
border: 1px solid #eee;
|
|
border-radius: 18px;
|
|
padding: 22px;
|
|
margin-bottom: 20px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
|
|
}
|
|
|
|
.modal-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
color: #c40000;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.form-row {
|
|
display: flex;
|
|
gap: 15px;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.form-group {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.form-group label {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: #444;
|
|
}
|
|
|
|
.form-group input,
|
|
.form-group select {
|
|
padding: 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 10px;
|
|
outline: none;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.modal-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 12px;
|
|
margin-top: 30px;
|
|
}
|
|
|
|
.btn {
|
|
padding: 12px 25px;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
font-weight: 600;
|
|
border: none;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.btn-cancel {
|
|
background: #f3f4f6;
|
|
color: #4b5563;
|
|
}
|
|
|
|
.btn-submit {
|
|
background: #c40000;
|
|
color: white;
|
|
}
|
|
|
|
.swal2-popup.modern-popup {
|
|
width: 360px !important;
|
|
border-radius: 26px !important;
|
|
padding: 1.5rem 1.3rem 1.3rem !important;
|
|
background: rgba(255, 255, 255, 0.98) !important;
|
|
backdrop-filter: blur(18px) !important;
|
|
-webkit-backdrop-filter: blur(18px) !important;
|
|
box-shadow: 0 25px 60px rgba(15, 23, 42, 0.18) !important;
|
|
border: 1px solid rgba(255, 255, 255, 0.7) !important;
|
|
}
|
|
|
|
.swal2-icon.swal2-warning {
|
|
border-color: rgba(196, 0, 0, 0.15) !important;
|
|
color: #c40000 !important;
|
|
width: 68px !important;
|
|
height: 68px !important;
|
|
margin-top: 5px !important;
|
|
}
|
|
|
|
.swal2-title.title-swal {
|
|
font-size: 20px !important;
|
|
font-weight: 700 !important;
|
|
color: #0f172a !important;
|
|
padding: 0 !important;
|
|
margin-top: 10px !important;
|
|
line-height: 1.4 !important;
|
|
}
|
|
|
|
.swal2-html-container {
|
|
font-size: 13px !important;
|
|
color: #64748b !important;
|
|
line-height: 1.7 !important;
|
|
margin: 10px 0 5px 0 !important;
|
|
padding: 0 10px !important;
|
|
}
|
|
|
|
.swal2-actions {
|
|
width: 100% !important;
|
|
display: flex !important;
|
|
gap: 10px !important;
|
|
margin-top: 20px !important;
|
|
padding: 0 5px !important;
|
|
}
|
|
|
|
.btn-confirm-swal {
|
|
flex: 1 !important;
|
|
background: linear-gradient(135deg, #c40000, #ff3b3b) !important;
|
|
color: white !important;
|
|
padding: 11px 14px !important;
|
|
border-radius: 14px !important;
|
|
font-weight: 600 !important;
|
|
font-size: 13px !important;
|
|
border: none !important;
|
|
margin: 0 !important;
|
|
box-shadow: 0 10px 25px rgba(196, 0, 0, 0.25) !important;
|
|
transition: all 0.25s ease !important;
|
|
}
|
|
|
|
.btn-confirm-swal:hover {
|
|
transform: translateY(-2px) scale(1.02) !important;
|
|
box-shadow: 0 14px 30px rgba(196, 0, 0, 0.35) !important;
|
|
}
|
|
|
|
.btn-cancel-swal {
|
|
flex: 1 !important;
|
|
background: #f8fafc !important;
|
|
color: #475569 !important;
|
|
padding: 11px 14px !important;
|
|
border-radius: 14px !important;
|
|
font-weight: 600 !important;
|
|
font-size: 13px !important;
|
|
border: 1px solid #e2e8f0 !important;
|
|
margin: 0 !important;
|
|
transition: all 0.25s ease !important;
|
|
}
|
|
|
|
.btn-cancel-swal:hover {
|
|
background: #eef2f7 !important;
|
|
transform: translateY(-2px) !important;
|
|
}
|
|
|
|
.swal2-success-ring {
|
|
border: 0.25em solid rgba(34, 197, 94, 0.25) !important;
|
|
}
|
|
|
|
.swal2-popup.swal2-toast {
|
|
border-radius: 14px !important;
|
|
}
|
|
|
|
.custom-swal-popup {
|
|
border-radius: 24px !important;
|
|
padding: 25px !important;
|
|
|
|
box-shadow:
|
|
0 20px 60px rgba(0, 0, 0, 0.18) !important;
|
|
|
|
border:
|
|
1px solid rgba(255, 255, 255, 0.7);
|
|
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
|
|
.custom-swal-title {
|
|
font-size: 24px !important;
|
|
font-weight: 700 !important;
|
|
color: #0f172a !important;
|
|
}
|
|
|
|
.custom-swal-button {
|
|
|
|
background: linear-gradient(135deg,
|
|
#2563eb,
|
|
#1d4ed8) !important;
|
|
|
|
color: white !important;
|
|
|
|
border: none !important;
|
|
|
|
padding:
|
|
12px 28px !important;
|
|
|
|
border-radius: 14px !important;
|
|
|
|
font-size: 15px !important;
|
|
|
|
font-weight: 600 !important;
|
|
|
|
transition: 0.3s ease;
|
|
|
|
box-shadow:
|
|
0 8px 20px rgba(37, 99, 235, 0.35);
|
|
}
|
|
|
|
.custom-swal-button:hover {
|
|
|
|
transform: translateY(-2px);
|
|
|
|
box-shadow:
|
|
0 12px 25px rgba(37, 99, 235, 0.45);
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="sidebar">
|
|
<h2>Sistem TBC</h2>
|
|
<ul class="menu">
|
|
<li><a href="{{ url('/dashboard') }}"><i data-lucide="layout-dashboard"></i> Dashboard</a></li>
|
|
<li class="active"><a href="{{ url('/data-pasien') }}"><i data-lucide="users"></i> Data Pasien</a></li>
|
|
<li><a href="{{ url('/skrining') }}"><i data-lucide="stethoscope"></i> Skrining</a></li>
|
|
@if(session('role') == 'super_admin')
|
|
<li>
|
|
<a href="{{ url('/kelola-admin') }}">
|
|
<i data-lucide="shield"></i> Kelola Admin
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="{{ url('/riwayat-aktivitas') }}">
|
|
<i data-lucide="activity"></i> Riwayat Aktivitas
|
|
</a>
|
|
</li>
|
|
@endif
|
|
<li>
|
|
<a href="{{ url('/pengaturan-akun') }}"><i data-lucide="user"></i> Akun</a>
|
|
</li>
|
|
</div>
|
|
|
|
<div class="main-content">
|
|
<div class="header-wrapper">
|
|
<h1 class="header-title">Data Pasien</h1>
|
|
</div>
|
|
|
|
<div class="top-bar">
|
|
<div class="action-header-left">
|
|
<button class="btn-tambah" onclick="openModalTambah()">
|
|
<i data-lucide="plus" size="18"></i> Tambah Pasien Baru
|
|
</button>
|
|
</div>
|
|
|
|
<div class="search-wrapper">
|
|
<div class="icon-container"><i data-lucide="search" size="18"></i></div>
|
|
<input type="text" id="searchInput" placeholder="Cari Nama atau NIK..." value="{{ request('search') }}">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Kotak Filtering (Accordion) -->
|
|
<div class="filter-accordion">
|
|
<div class="filter-header" onclick="toggleFilter()">
|
|
<h4><i data-lucide="filter" size="18"></i> Pencarian Lanjutan & Export</h4>
|
|
<i data-lucide="chevron-down" id="filterIcon"></i>
|
|
</div>
|
|
<div class="filter-content {{ (request('status') || request('desa') || request('start_date')) ? 'active' : '' }}" id="filterContent">
|
|
<form action="{{ url('/data-pasien') }}" method="GET" id="filterForm">
|
|
<input type="hidden" name="search" id="hiddenSearch" value="{{ request('search') }}">
|
|
|
|
<div class="filter-grid">
|
|
<div class="filter-group">
|
|
<label>Status Kesehatan</label>
|
|
<select name="status" id="filterStatus">
|
|
<option value="">Semua Status</option>
|
|
<option value="Masih Proses" {{ request('status') == 'Masih Proses' ? 'selected' : '' }}>Masih Proses</option>
|
|
<option value="Sembuh" {{ request('status') == 'Sembuh' ? 'selected' : '' }}>Sembuh</option>
|
|
<option value="Meninggal" {{ request('status') == 'Meninggal' ? 'selected' : '' }}>Meninggal</option>
|
|
<option value="Gagal" {{ request('status') == 'Gagal' ? 'selected' : '' }}>Gagal</option>
|
|
</select>
|
|
</div>
|
|
<div class="filter-group">
|
|
<label>Data Per Desa</label>
|
|
<input type="text" name="desa" placeholder="Nama Desa..." value="{{ request('desa') }}">
|
|
</div>
|
|
<div class="filter-group">
|
|
<label>Tanggal Mulai Pengobatan</label>
|
|
<input type="date" max="{{ date('Y-m-d') }}" name="start_date" value="{{ request('start_date') }}">
|
|
</div>
|
|
<div class="filter-group">
|
|
<label>Tanggal Selesai Pengobatan</label>
|
|
<input type="date" name="end_date" value="{{ request('end_date') }}">
|
|
</div>
|
|
@if(session('role') == 'super_admin')
|
|
<div class="filter-group">
|
|
<label>Filter Fasyankes</label>
|
|
<select name="fasyankes">
|
|
<option value="">Semua Fasyankes</option>
|
|
|
|
@foreach($listFasyankes as $f)
|
|
<option
|
|
value="{{ $f->nama_fasyankes }}"
|
|
{{ request('fasyankes') == $f->nama_fasyankes ? 'selected' : '' }}>
|
|
{{ $f->nama_fasyankes }}
|
|
</option>
|
|
@endforeach
|
|
|
|
</select>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
<div class="filter-actions">
|
|
<a href="{{ url('/data-pasien') }}" class="btn-reset">
|
|
<i data-lucide="refresh-cw" size="16"></i> Reset Filter
|
|
</a>
|
|
<button type="button" class="btn-export" onclick="submitExport()">
|
|
<i data-lucide="download" size="16"></i> Export Excel
|
|
</button>
|
|
<button type="submit" class="btn-cari">
|
|
<i data-lucide="search" size="16"></i> Cari Data
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th class="col-no">No.</th>
|
|
<th class="col-nama">Nama</th>
|
|
<th class="col-nik">NIK</th>
|
|
<th class="col-tgl">Tgl Lahir</th>
|
|
<th class="col-jk">L/P</th>
|
|
<th class="col-alamat">Alamat</th>
|
|
<th class="col-telp">No. Telp</th>
|
|
|
|
@if(session('role') == 'super_admin')
|
|
<th class="col-email">Email</th>
|
|
<th class="col-status">Fasyankes</th>
|
|
@endif
|
|
<th class="col-aksi">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="pasienTableBody">
|
|
@foreach($pasiens as $p)
|
|
<tr>
|
|
<td class="col-no">{{ ($pasiens->currentPage() - 1) * $pasiens->perPage() + $loop->iteration }}</td>
|
|
<td class="col-nama">{{ $p->nama_lengkap }}</td>
|
|
<td>{{ $p->nik }}</td>
|
|
<td>{{ $p->tgl_lahir ?? '-' }}</td>
|
|
<td style="text-align:center;">{{ $p->jenis_kelamin }}</td>
|
|
<td>{{ $p->alamat }}</td>
|
|
<td>{{ $p->no_telp }}</td>
|
|
|
|
@if(session('role') == 'super_admin')
|
|
<td>{{ $p->email ?? '-' }}</td>
|
|
<td>{{ $p->nama_fasyankes ?? '-' }}</td>
|
|
@endif
|
|
|
|
<td class="col-aksi">
|
|
<div class="action-btns">
|
|
<button class="btn-icon info" onclick="window.location.href='/detail-pasien/{{ $p->id_medis }}'" title="Detail">
|
|
<i data-lucide="info" size="18"></i>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn-icon edit btn-edit-pasien"
|
|
data-item='@json($p)'
|
|
onclick="prepareEdit(this.dataset.item)"
|
|
title="Edit">
|
|
<i data-lucide="edit-3" size="18"></i>
|
|
</button>
|
|
<button class="btn-icon info"
|
|
onclick="openPindahFasyankes({{ $p->id_user }}, '{{ $p->nama_lengkap }}', '{{ $p->nama_fasyankes }}')"
|
|
title="Pindah Fasyankes">
|
|
<i data-lucide="hospital" size="18"></i>
|
|
</button>
|
|
<button class="btn-icon trash" onclick="aksiHapus(this, {{ $p->id_user }})" title="Hapus">
|
|
<i data-lucide="trash-2" size="18"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="pagination-wrapper">
|
|
<div class="pagination-info">
|
|
<span class="text-muted">
|
|
Menampilkan <b>{{ $pasiens->firstItem() }}</b> sampai <b>{{ $pasiens->lastItem() }}</b> dari <b>{{ $pasiens->total() }}</b> pasien
|
|
</span>
|
|
</div>
|
|
<div class="pagination-links">
|
|
{{ $pasiens->appends(request()->input())->links('pagination::bootstrap-4') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
|
|
@csrf
|
|
</form>
|
|
|
|
<!-- Modal Pasien -->
|
|
<div class="modal-overlay" id="modalPasien">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h3 id="modalTitle">Tambah Pasien Baru</h3>
|
|
<button class="btn-icon info" onclick="closeModal()" style="width: 30px; height: 30px;"><i data-lucide="x" size="18"></i></button>
|
|
</div>
|
|
<form id="pasienForm" method="POST" enctype="multipart/form-data">
|
|
<div class="modal-card">
|
|
|
|
@csrf
|
|
|
|
<input type="hidden" name="form_mode" id="form_mode" value="create">
|
|
<input type="hidden" name="id_user" id="form_id_user">
|
|
|
|
<!-- ========================= -->
|
|
<!-- DATA IDENTITAS -->
|
|
<!-- ========================= -->
|
|
|
|
<div style="margin-bottom:25px;">
|
|
<h4 style="color:#c40000;margin-bottom:15px;">
|
|
Data Identitas Pasien
|
|
</h4>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Nama Lengkap Pasien</label>
|
|
<input type="text" name="nama" id="form_nama" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>NIK</label>
|
|
<input type="text" name="nik" id="form_nik" maxlength="16" required>
|
|
<small id="nikError" style="color:red; display:none;">
|
|
NIK harus 16 digit!
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Email</label>
|
|
<input type="email" name="email" id="form_email" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>No. Telepon</label>
|
|
<input type="text" name="telp" id="form_telp" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Tanggal Lahir</label>
|
|
<input type="date" max="{{ date('Y-m-d') }}" name="tgl_lahir" id="form_tgl_lahir" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Jenis Kelamin</label>
|
|
<select name="jenis_kelamin" id="form_jk" required>
|
|
<option value="">Pilih</option>
|
|
<option value="L">Laki-laki</option>
|
|
<option value="P">Perempuan</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
@if(session('role') == 'super_admin')
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label>Pilih Fasyankes</label>
|
|
|
|
<select name="nama_fasyankes" id="form_fasyankes" required>
|
|
<option value="">Pilih Fasyankes</option>
|
|
|
|
@foreach($listFasyankes as $f)
|
|
<option value="{{ $f->nama_fasyankes }}">
|
|
{{ $f->nama_fasyankes }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- ALAMAT PINDAH KE IDENTITAS -->
|
|
<div style="margin-top:20px;">
|
|
<p style="font-weight:700;margin-bottom:15px;">
|
|
Data Alamat
|
|
</p>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
<label>Kecamatan</label>
|
|
|
|
<select name="kecamatan"
|
|
id="form_kecamatan"
|
|
required>
|
|
|
|
<option value="">
|
|
Pilih Kecamatan
|
|
</option>
|
|
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Desa</label>
|
|
|
|
<select name="desa"
|
|
id="form_desa"
|
|
required
|
|
disabled>
|
|
|
|
<option value="">
|
|
Pilih Desa
|
|
</option>
|
|
|
|
</select>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
<label>Dusun</label>
|
|
|
|
<input
|
|
type="text"
|
|
name="dusun"
|
|
id="form_dusun"
|
|
placeholder="Masukkan dusun"
|
|
required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>RT / RW</label>
|
|
|
|
<input type="text"
|
|
name="rtrw"
|
|
id="rtrw_input"
|
|
required>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ========================= -->
|
|
<!-- DATA MEDIS -->
|
|
<!-- ========================= -->
|
|
|
|
<div class="modal-card">
|
|
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:15px;">
|
|
|
|
<h4 style="color:#c40000;">
|
|
Data Medis Pengobatan
|
|
</h4>
|
|
|
|
<div id="pengobatanActionWrapper">
|
|
|
|
<button type="button"
|
|
id="btnTambahPengobatan"
|
|
style="display:none;
|
|
background:#c40000;
|
|
color:white;
|
|
border:none;
|
|
padding:10px 15px;
|
|
border-radius:10px;
|
|
font-weight:600;
|
|
cursor:pointer;
|
|
transition:0.2s;
|
|
"
|
|
onclick="tambahRiwayatPengobatan()">
|
|
+ Tambah Pengobatan
|
|
</button>
|
|
|
|
<small
|
|
id="notePengobatan"
|
|
style="
|
|
display:none;
|
|
margin-top:8px;
|
|
color:#c40000;
|
|
font-size:12px;
|
|
font-weight:600;
|
|
">
|
|
</small>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="containerRiwayatPengobatan"></div>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button"
|
|
class="btn btn-cancel"
|
|
onclick="closeModal()">
|
|
Batal
|
|
</button>
|
|
|
|
<button type="submit"
|
|
class="btn btn-submit"
|
|
id="btnSubmitForm">
|
|
Simpan Pasien
|
|
</button>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- MODAL PINDAH FASYANKES -->
|
|
<div class="modal-overlay" id="modalPindahFasyankes">
|
|
<div class="modal-content" style="width:500px;">
|
|
|
|
<div class="modal-header">
|
|
<h3>Pindahkan Pasien</h3>
|
|
|
|
<button class="btn-icon info"
|
|
onclick="closeModalPindah()"
|
|
style="width:30px;height:30px;">
|
|
<i data-lucide="x" size="18"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<form id="formPindahFasyankes">
|
|
@csrf
|
|
|
|
<input type="hidden" id="pindah_id_user">
|
|
|
|
<div class="form-group" style="margin-bottom:20px;">
|
|
<label>Nama Pasien</label>
|
|
<input type="text" id="pindah_nama" readonly style="background:#f8fafc;">
|
|
</div>
|
|
|
|
<div class="form-group" style="margin-bottom:20px;">
|
|
<label>Fasyankes Saat Ini</label>
|
|
<input type="text" id="pindah_fasyankes_lama" readonly style="background:#f8fafc;">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Pindah Ke Fasyankes</label>
|
|
|
|
<select id="pindah_fasyankes_baru" required>
|
|
<option value="">Pilih Fasyankes</option>
|
|
|
|
@foreach($listFasyankes as $f)
|
|
<option value="{{ $f->nama_fasyankes }}">
|
|
{{ $f->nama_fasyankes }}
|
|
</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button"
|
|
class="btn btn-cancel"
|
|
onclick="closeModalPindah()">
|
|
Batal
|
|
</button>
|
|
|
|
<button type="submit"
|
|
class="btn btn-submit">
|
|
Pindahkan
|
|
</button>
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function parseDateSafe(dateStr) {
|
|
if (!dateStr) return null;
|
|
|
|
const parts = dateStr.split('-');
|
|
return new Date(parts[0], parts[1] - 1, parts[2]);
|
|
}
|
|
// DEFINE GLOBAL VARIABLES
|
|
const modal = document.getElementById('modalPasien');
|
|
const form = document.getElementById('pasienForm');
|
|
|
|
const today = new Date().toISOString().split('T')[0];
|
|
const wilayahJember = {
|
|
|
|
"AJUNG": {
|
|
|
|
"AJUNG": [
|
|
"KRAJAN",
|
|
"AJUNG KULON",
|
|
"AJUNG WETAN",
|
|
"CURAH KATES",
|
|
"GUMUK KERANG",
|
|
"KIDUL BESUK",
|
|
"KLANCENG",
|
|
"LIMBUNGSARI",
|
|
"SUMURAN"
|
|
],
|
|
|
|
"KLOMPANGAN": [
|
|
"KRAJAN",
|
|
"CURAH KATES",
|
|
"DURENAN",
|
|
"GRINTINGAN",
|
|
"GUMUK KEMBAR",
|
|
"PONDOK LABU",
|
|
"SUMURAN"
|
|
],
|
|
|
|
"MANGARAN": [
|
|
"KRAJAN",
|
|
"CURAH MANIS",
|
|
"CURAH TEPAS",
|
|
"GUMUK WULUH",
|
|
"KEBUN PRING",
|
|
"LONCATAN",
|
|
"PATEMON",
|
|
"RENTENG",
|
|
"SIDOMULYO"
|
|
],
|
|
|
|
"PANCAKARYA": [
|
|
"CURAH RENTENG",
|
|
"CURAH WELUT",
|
|
"GUMUK SEGAWE",
|
|
"KEDUNG KWALI",
|
|
"KRASAK",
|
|
"KRESEK"
|
|
],
|
|
|
|
"ROWO INDAH": [
|
|
"LANGSEPAN",
|
|
"ROWO"
|
|
],
|
|
|
|
"SUKAMAKMUR": [
|
|
"CURAH KENDAL",
|
|
"CURAH REJO",
|
|
"MANGARAN",
|
|
"LANGSATAN",
|
|
"PLALANGAN"
|
|
],
|
|
|
|
"WIROWONGSO": [
|
|
"BESUK",
|
|
"PENANGGUNGAN",
|
|
"RENES",
|
|
"SUMBEREJO"
|
|
]
|
|
|
|
},
|
|
|
|
"AMBULU": [
|
|
"SUMBERREJO",
|
|
"ANDONGSARI",
|
|
"SABRANG",
|
|
"AMBULU",
|
|
"PONTANG",
|
|
"KARANGANYAR",
|
|
"TEGALSARI"
|
|
],
|
|
|
|
"ARJASA": [
|
|
"KEMUNING LOR",
|
|
"DARSONO",
|
|
"ARJASA",
|
|
"BITING",
|
|
"CANDIJATI",
|
|
"KAMAL"
|
|
],
|
|
|
|
"BALUNG": [
|
|
"KARANG DUREN",
|
|
"KARANG SEMANDING",
|
|
"TUTUL",
|
|
"BALUNG KULON",
|
|
"BALUNG KIDUL",
|
|
"BALUNG LOR",
|
|
"GUMELAR",
|
|
"CURAH LELE"
|
|
],
|
|
|
|
"BANGSALSARI": [
|
|
"KARANGSONO",
|
|
"SUKOREJO",
|
|
"PETUNG",
|
|
"TISNOGAMBAR",
|
|
"LANGKAP",
|
|
"BANGSALSARI",
|
|
"GAMBIRONO",
|
|
"CURAH KALONG",
|
|
"TUGUSARI",
|
|
"BANJARSARI",
|
|
"BADEAN"
|
|
],
|
|
|
|
"GUMUKMAS": [
|
|
"KEPANJEN",
|
|
"MAYANGAN",
|
|
"MENAMPU",
|
|
"BAGOREJO",
|
|
"GUMUKMAS",
|
|
"PURWOSARI",
|
|
"TEMBOKREJO",
|
|
"KARANG REJO"
|
|
],
|
|
|
|
"JELBUK": [
|
|
"PANDUMAN",
|
|
"JELBUK",
|
|
"SUKOWIRYO",
|
|
"SUGER KIDUL",
|
|
"SUKO JEMBER",
|
|
"SUCO PENGEPOK"
|
|
],
|
|
|
|
"JENGGAWAH": [
|
|
"KEMUNINGSARI KIDUL",
|
|
"KERTONEGORO",
|
|
"JATISARI",
|
|
"SRUNI",
|
|
"CANGKRING",
|
|
"WONOJATI",
|
|
"JENGGAWAH",
|
|
"JATIMULYO"
|
|
],
|
|
|
|
"JOMBANG": [
|
|
"KETING",
|
|
"JOMBANG",
|
|
"PADOMASAN",
|
|
"NGAMPELREJO",
|
|
"WRINGIN AGUNG",
|
|
"SARI MULYO"
|
|
],
|
|
|
|
"KALISAT": [
|
|
"GAMBIRAN",
|
|
"PLALANGAN",
|
|
"AJUNG",
|
|
"GLAGAHWERO",
|
|
"SUMBER JERUK",
|
|
"GUMUKSARI",
|
|
"PATEMPURAN",
|
|
"KALISAT",
|
|
"SUMBER KETEMPAH",
|
|
"SUKORENO",
|
|
"SUMBER KALONG",
|
|
"SEBANEN"
|
|
],
|
|
|
|
"KALIWATES": [
|
|
"MANGLI",
|
|
"SEMPUSARI",
|
|
"KALIWATES",
|
|
"TEGAL BESAR",
|
|
"JEMBER KIDUL",
|
|
"KEPATIHAN",
|
|
"KEBON AGUNG"
|
|
],
|
|
|
|
"KENCONG": [
|
|
"PASEBAN",
|
|
"CAKRU",
|
|
"KRATON",
|
|
"WONOREJO",
|
|
"KENCONG"
|
|
],
|
|
|
|
"LEDOKOMBO": [
|
|
"SUREN",
|
|
"SUMBER SALAK",
|
|
"SUMBER BULUS",
|
|
"SUMBER LESUNG",
|
|
"LEMBENGAN",
|
|
"SUMBER ANGET",
|
|
"LEDOKOMBO",
|
|
"SLATENG",
|
|
"SUKOGIDRI",
|
|
"KARANG PAITON"
|
|
],
|
|
|
|
"MAYANG": [
|
|
"SEPUTIH",
|
|
"SIDOMUKTI",
|
|
"SUMBER KEJAYAN",
|
|
"TEGALREJO",
|
|
"TEGALWARU",
|
|
"MAYANG",
|
|
"MRAWAN"
|
|
],
|
|
|
|
"MUMBULSARI": [
|
|
"KAWANGREJO",
|
|
"TAMANSARI",
|
|
"SUCO",
|
|
"LAMPEJI",
|
|
"MUMBULSARI",
|
|
"LENGKONG",
|
|
"KARANGKEDAWUNG"
|
|
],
|
|
|
|
"PAKUSARI": [
|
|
"KERTOSARI",
|
|
"PAKUSARI",
|
|
"JATIAN",
|
|
"SUBO",
|
|
"SUMBERPINANG",
|
|
"BEDADUNG",
|
|
"PATEMON"
|
|
],
|
|
|
|
"PANTI": [
|
|
"KEMUNINGSARI LOR",
|
|
"GLAGAHWERO",
|
|
"SERUT",
|
|
"PANTI",
|
|
"PAKIS",
|
|
"SUCI",
|
|
"KEMIRI"
|
|
],
|
|
|
|
"PATRANG": [
|
|
"GEBANG",
|
|
"JEMBER LOR",
|
|
"PATRANG",
|
|
"BARATAN",
|
|
"BINTORO",
|
|
"SLAWU",
|
|
"JUMERTO",
|
|
"BANJARSENGON"
|
|
],
|
|
|
|
"PUGER": [
|
|
"MOJOMULYO",
|
|
"MOJOSARI",
|
|
"PUGER KULON",
|
|
"PUGER WETAN",
|
|
"GRENDEN",
|
|
"MLOKOREJO",
|
|
"KASIYAN",
|
|
"KASIYAN TIMUR",
|
|
"WONOSARI",
|
|
"JAMBEARUM",
|
|
"BAGON",
|
|
"WRINGIN TELU"
|
|
]
|
|
};
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
lucide.createIcons();
|
|
initWilayahDropdown();
|
|
const searchInput = document.getElementById('searchInput');
|
|
const hiddenSearch = document.getElementById('hiddenSearch');
|
|
searchInput.addEventListener('input', () => {
|
|
hiddenSearch.value = searchInput.value;
|
|
});
|
|
});
|
|
|
|
function initWilayahDropdown() {
|
|
|
|
const kecamatan =
|
|
document.getElementById('form_kecamatan');
|
|
|
|
const desa = document.getElementById('form_desa');
|
|
const dusun = document.getElementById('form_dusun');
|
|
|
|
kecamatan.innerHTML =
|
|
'<option value="">Pilih Kecamatan</option>';
|
|
|
|
Object.keys(wilayahJember)
|
|
.sort()
|
|
.forEach(item => {
|
|
|
|
kecamatan.innerHTML +=
|
|
`<option value="${item}">
|
|
${item}
|
|
</option>`;
|
|
});
|
|
|
|
kecamatan.addEventListener('change', function() {
|
|
|
|
desa.innerHTML = '<option value="">Pilih Desa</option>';
|
|
|
|
dusun.value = '';
|
|
|
|
if (!this.value) {
|
|
desa.disabled = true;
|
|
return;
|
|
}
|
|
|
|
Object.keys(wilayahJember[this.value]).forEach(item => {
|
|
|
|
desa.innerHTML += `
|
|
<option value="${item}">
|
|
${item}
|
|
</option>
|
|
`;
|
|
|
|
});
|
|
|
|
desa.disabled = false;
|
|
|
|
desa.addEventListener('change', function() {
|
|
|
|
dusun.value = '';
|
|
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function toggleFilter() {
|
|
const content = document.getElementById('filterContent');
|
|
const icon = document.getElementById('filterIcon');
|
|
content.classList.toggle('active');
|
|
icon.style.transform = content.classList.contains('active') ? 'rotate(180deg)' : 'rotate(0deg)';
|
|
}
|
|
|
|
function submitExport() {
|
|
const f = document.getElementById('filterForm');
|
|
const originalAction = f.action;
|
|
f.action = "{{ route('pasien.export') }}";
|
|
f.submit();
|
|
f.action = originalAction;
|
|
}
|
|
|
|
function updateStatusPengobatan(status) {
|
|
|
|
const btn = document.getElementById('btnTambahPengobatan');
|
|
const note = document.getElementById('notePengobatan');
|
|
|
|
if (!btn || !note) return;
|
|
|
|
// default = boleh tambah
|
|
btn.disabled = false;
|
|
btn.style.opacity = '1';
|
|
btn.style.cursor = 'pointer';
|
|
btn.style.background = '#c40000';
|
|
|
|
note.style.display = 'none';
|
|
note.innerHTML = '';
|
|
|
|
// HANYA status berikut yang tidak boleh tambah pengobatan
|
|
if (
|
|
status === 'Masih Proses' ||
|
|
status === 'Gagal' ||
|
|
status === 'Meninggal'
|
|
) {
|
|
|
|
btn.disabled = true;
|
|
|
|
btn.style.opacity = '0.55';
|
|
btn.style.cursor = 'not-allowed';
|
|
btn.style.background = '#9ca3af';
|
|
|
|
note.style.display = 'block';
|
|
|
|
if (status === 'Masih Proses') {
|
|
|
|
note.innerHTML =
|
|
'pasien masih menjalani pengobatan aktif.';
|
|
|
|
} else if (status === 'Gagal') {
|
|
|
|
note.innerHTML =
|
|
'Pasien gagal pengobatan.';
|
|
|
|
} else if (status === 'Meninggal') {
|
|
|
|
note.innerHTML =
|
|
'Pasien telah meninggal.';
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleStatusPengobatanChange() {
|
|
|
|
const semuaStatus =
|
|
document.querySelectorAll('.status-pengobatan-select');
|
|
|
|
if (semuaStatus.length === 0) return;
|
|
|
|
// ambil status pengobatan TERAKHIR
|
|
const statusTerakhir =
|
|
semuaStatus[semuaStatus.length - 1].value;
|
|
|
|
updateStatusPengobatan(statusTerakhir);
|
|
}
|
|
|
|
function updateUploadTahap(parent) {
|
|
|
|
const status =
|
|
parent.querySelector(
|
|
'.status-pengobatan-select'
|
|
)?.value;
|
|
|
|
const mulai =
|
|
parent.querySelector(
|
|
'.tgl-mulai-input'
|
|
)?.value;
|
|
|
|
if (!mulai) return;
|
|
|
|
const hari =
|
|
Math.floor(
|
|
(
|
|
new Date() -
|
|
new Date(mulai)
|
|
) / 86400000
|
|
);
|
|
|
|
const fileAwal =
|
|
parent.querySelector('.file-awal');
|
|
|
|
const file56 =
|
|
parent.querySelector('.file-56');
|
|
|
|
const file168 =
|
|
parent.querySelector('.file-168');
|
|
|
|
if (
|
|
status === 'Gagal' ||
|
|
status === 'Meninggal'
|
|
) {
|
|
|
|
fileAwal.disabled = true;
|
|
file56.disabled = true;
|
|
file168.disabled = true;
|
|
|
|
return;
|
|
}
|
|
|
|
fileAwal.disabled = false;
|
|
|
|
file56.disabled =
|
|
hari < 56;
|
|
|
|
file168.disabled =
|
|
hari < 168;
|
|
}
|
|
|
|
function prepareEdit(p) {
|
|
if (typeof p === "string") {
|
|
p = JSON.parse(p);
|
|
} else {
|
|
p = JSON.parse(JSON.stringify(p));
|
|
}
|
|
|
|
form.reset();
|
|
document.getElementById("form_desa").disabled = true;
|
|
document.getElementById("form_dusun").value = "";
|
|
|
|
document.getElementById("form_desa").innerHTML =
|
|
'<option value="">Pilih Desa</option>';
|
|
|
|
document.getElementById('containerRiwayatPengobatan').innerHTML = '';
|
|
|
|
document.getElementById('modalTitle').innerText =
|
|
'Edit Data Pasien';
|
|
|
|
document.getElementById('btnSubmitForm').innerText =
|
|
'Update Pasien';
|
|
|
|
document.getElementById('form_mode').value = 'edit';
|
|
|
|
document.getElementById('btnTambahPengobatan').style.display = 'inline-block';
|
|
|
|
document.getElementById('form_nama').value =
|
|
p.nama_lengkap || '';
|
|
|
|
document.getElementById('form_nik').value =
|
|
p.nik || '';
|
|
|
|
document.getElementById('form_telp').value =
|
|
p.no_telp || '';
|
|
|
|
document.getElementById('form_tgl_lahir').value =
|
|
p.tgl_lahir || '';
|
|
|
|
document.getElementById('form_jk').value =
|
|
p.jenis_kelamin || '';
|
|
|
|
document.getElementById('form_email').value =
|
|
p.email || '';
|
|
document.getElementById('rtrw_input').value =
|
|
(p.rt_rw || '').replace('RT/RW ', '');
|
|
|
|
@if(session('role') == 'super_admin')
|
|
document.getElementById('form_fasyankes').value =
|
|
p.nama_fasyankes || '';
|
|
@endif
|
|
|
|
if (p.alamat) {
|
|
|
|
const bagian = p.alamat.split(', ');
|
|
|
|
const dusunValue =
|
|
bagian[0] || '';
|
|
|
|
const desaValue =
|
|
bagian[2] ?
|
|
bagian[2].replace(/^Desa\s+/i, '') :
|
|
'';
|
|
|
|
const kecamatanValue =
|
|
bagian[3] ?
|
|
bagian[3].replace(/^Kecamatan\s+/i, '') :
|
|
'';
|
|
|
|
setAlamatEdit(
|
|
kecamatanValue,
|
|
desaValue,
|
|
dusunValue
|
|
);
|
|
}
|
|
|
|
// =========================
|
|
// AMBIL DATA MEDIS
|
|
// =========================
|
|
|
|
fetch(`/pasien/${p.id_user}/riwayat-pengobatan`)
|
|
.then(res => res.json())
|
|
.then(res => {
|
|
|
|
const container =
|
|
document.getElementById('containerRiwayatPengobatan');
|
|
|
|
container.innerHTML = '';
|
|
|
|
if (
|
|
res.success &&
|
|
Array.isArray(res.data) &&
|
|
res.data.length > 0
|
|
) {
|
|
|
|
res.data.forEach(item => {
|
|
|
|
item.mode = 'edit';
|
|
|
|
tambahFormPengobatan(item);
|
|
|
|
});
|
|
|
|
const semuaStatus =
|
|
document.querySelectorAll('.status-pengobatan-select');
|
|
|
|
if (semuaStatus.length > 0) {
|
|
|
|
const statusTerakhir =
|
|
semuaStatus[semuaStatus.length - 1].value;
|
|
|
|
updateStatusPengobatan(statusTerakhir);
|
|
}
|
|
|
|
// ======================================
|
|
// PAKSA SEMUA RULE UPLOAD DIEKSEKUSI
|
|
// ======================================
|
|
|
|
setTimeout(() => {
|
|
|
|
document
|
|
.querySelectorAll('.status-pengobatan-select')
|
|
.forEach(select => {
|
|
|
|
handleStatusUpload(select);
|
|
|
|
});
|
|
|
|
const terakhir =
|
|
document.querySelectorAll(
|
|
'.status-pengobatan-select'
|
|
);
|
|
|
|
if (terakhir.length > 0) {
|
|
|
|
updateStatusPengobatan(
|
|
terakhir[terakhir.length - 1].value
|
|
);
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
}
|
|
|
|
})
|
|
.catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
});
|
|
|
|
form.action =
|
|
"/update-pasien/" + p.id_user;
|
|
|
|
modal.style.display = 'flex';
|
|
|
|
lucide.createIcons();
|
|
}
|
|
|
|
function setAlamatEdit(
|
|
kecamatan,
|
|
desa,
|
|
dusun
|
|
) {
|
|
|
|
document.getElementById(
|
|
'form_kecamatan'
|
|
).value = kecamatan;
|
|
|
|
document.getElementById(
|
|
'form_kecamatan'
|
|
).dispatchEvent(
|
|
new Event('change')
|
|
);
|
|
|
|
setTimeout(() => {
|
|
|
|
document.getElementById(
|
|
'form_desa'
|
|
).value = desa;
|
|
|
|
document.getElementById(
|
|
'form_desa'
|
|
).dispatchEvent(
|
|
new Event('change')
|
|
);
|
|
|
|
setTimeout(() => {
|
|
|
|
document.getElementById(
|
|
'form_dusun'
|
|
).value = dusun;
|
|
|
|
}, 50);
|
|
|
|
}, 50);
|
|
}
|
|
|
|
function closeModal() {
|
|
|
|
modal.style.display = "none";
|
|
|
|
form.reset();
|
|
|
|
document.getElementById("containerRiwayatPengobatan").innerHTML = "";
|
|
|
|
document.getElementById("form_desa").disabled = true;
|
|
|
|
document.getElementById("form_dusun").value = "";
|
|
|
|
}
|
|
|
|
function openModalTambah() {
|
|
|
|
form.reset();
|
|
document.getElementById('form_desa').disabled = true;
|
|
document.getElementById('form_dusun').value = '';
|
|
|
|
document.getElementById('containerRiwayatPengobatan').innerHTML = '';
|
|
|
|
document.getElementById('modalTitle').innerText =
|
|
'Tambah Pasien Baru';
|
|
|
|
document.getElementById('btnSubmitForm').innerText =
|
|
'Simpan Pasien';
|
|
|
|
document.getElementById('form_mode').value = 'create';
|
|
document.getElementById('btnTambahPengobatan').style.display = 'none';
|
|
|
|
document.getElementById('form_id_user').value = '';
|
|
|
|
form.action = "/tambah-pasien";
|
|
|
|
tambahFormPengobatan({
|
|
mode: 'create'
|
|
});
|
|
const note =
|
|
document.getElementById('notePengobatan');
|
|
|
|
if (note) {
|
|
|
|
note.style.display = 'none';
|
|
|
|
note.innerHTML = '';
|
|
}
|
|
|
|
modal.style.display = 'flex';
|
|
|
|
lucide.createIcons();
|
|
}
|
|
|
|
function hitungTanggalSelesai() {
|
|
const tglMulai = document.getElementById('form_mulai').value;
|
|
if (tglMulai) {
|
|
const date = new Date(tglMulai);
|
|
date.setDate(date.getDate() + 167);
|
|
document.getElementById('form_selesai').value = date.toISOString().split('T')[0];
|
|
}
|
|
}
|
|
|
|
// Helper: Kapitalisasi & RT/RW
|
|
document.querySelectorAll('input[type="text"]').forEach(input => {
|
|
input.addEventListener('input', function() {
|
|
let pos = this.selectionStart;
|
|
this.value = this.value.toUpperCase();
|
|
this.setSelectionRange(pos, pos);
|
|
});
|
|
});
|
|
|
|
document.getElementById('rtrw_input').addEventListener('input', function(e) {
|
|
let val = e.target.value.replace(/\D/g, '');
|
|
if (val.length > 2) val = val.slice(0, 2) + '/' + val.slice(2, 4);
|
|
e.target.value = val;
|
|
});
|
|
|
|
function updateStatus(selectElement, id) {
|
|
const statusValue = selectElement.value;
|
|
const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
|
selectElement.disabled = true;
|
|
|
|
fetch(`/update-status/${id}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': token,
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify({
|
|
status_kesehatan: statusValue
|
|
})
|
|
})
|
|
.then(async response => {
|
|
const data = await response.json();
|
|
if (!response.ok) throw new Error(data.message || 'Gagal update');
|
|
return data;
|
|
})
|
|
.then(() => {
|
|
selectElement.disabled = false;
|
|
Swal.fire({
|
|
toast: true,
|
|
position: 'top-end',
|
|
icon: 'success',
|
|
title: 'Status diperbarui',
|
|
showConfirmButton: false,
|
|
timer: 2000
|
|
});
|
|
})
|
|
.catch(error => {
|
|
selectElement.disabled = false;
|
|
Swal.fire('Error!', error.message, 'error');
|
|
});
|
|
}
|
|
|
|
document.getElementById('form_nik').addEventListener('input', function() {
|
|
this.value = this.value.replace(/\D/g, '');
|
|
const error = document.getElementById('nikError');
|
|
const btn = document.getElementById('btnSubmitForm');
|
|
if (this.value.length !== 16 && this.value.length > 0) {
|
|
error.style.display = 'block';
|
|
btn.disabled = true;
|
|
} else {
|
|
error.style.display = 'none';
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
|
|
let searchTimeout;
|
|
|
|
document.getElementById('searchInput').addEventListener('keyup', function() {
|
|
|
|
clearTimeout(searchTimeout);
|
|
|
|
searchTimeout = setTimeout(() => {
|
|
|
|
const searchValue = this.value;
|
|
|
|
const url = new URL(window.location.href);
|
|
|
|
if (searchValue) {
|
|
url.searchParams.set('search', searchValue);
|
|
} else {
|
|
url.searchParams.delete('search');
|
|
}
|
|
|
|
window.location.href = url.toString();
|
|
|
|
}, 500);
|
|
});
|
|
|
|
function aksiHapus(btn, id) {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Hapus Pasien?',
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
Data pasien akan dihapus permanen dari sistem dan tidak dapat dikembalikan lagi.
|
|
</div>
|
|
`,
|
|
width: '360px',
|
|
showCancelButton: true,
|
|
confirmButtonText: `
|
|
<div style="display:flex;align-items:center;justify-content:center;gap:6px;">
|
|
<i data-lucide="trash-2" style="width:16px;height:16px;"></i>
|
|
<span>Hapus</span>
|
|
</div>
|
|
`,
|
|
cancelButtonText: `
|
|
<div style="display:flex;align-items:center;justify-content:center;gap:6px;">
|
|
<i data-lucide="x" style="width:16px;height:16px;"></i>
|
|
<span>Batal</span>
|
|
</div>
|
|
`,
|
|
reverseButtons: true,
|
|
focusCancel: true,
|
|
allowOutsideClick: false,
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal',
|
|
cancelButton: 'btn-cancel-swal'
|
|
},
|
|
didOpen: () => {
|
|
lucide.createIcons();
|
|
}
|
|
}).then((result) => {
|
|
|
|
if (result.isConfirmed) {
|
|
|
|
fetch(`/hapus-pasien/${id}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'X-CSRF-TOKEN': document
|
|
.querySelector('meta[name="csrf-token"]')
|
|
.getAttribute('content')
|
|
}
|
|
})
|
|
.then(() => {
|
|
|
|
btn.closest('tr').remove();
|
|
refreshIcons();
|
|
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil Dihapus',
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
Data pasien berhasil dihapus dari sistem.
|
|
</div>
|
|
`,
|
|
width: '340px',
|
|
timer: 1800,
|
|
showConfirmButton: false,
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal'
|
|
}
|
|
});
|
|
|
|
})
|
|
.catch(() => {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Gagal',
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
Terjadi kesalahan saat menghapus data pasien.
|
|
</div>
|
|
`,
|
|
width: '340px',
|
|
confirmButtonText: 'Tutup',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
function generateRiwayatForm(index, data = {}) {
|
|
|
|
/*
|
|
==========================================================
|
|
STATUS & FILE
|
|
==========================================================
|
|
*/
|
|
|
|
const statusPengobatan =
|
|
data.status_kesehatan ?? 'Masih Proses';
|
|
|
|
const jumlahFile =
|
|
parseInt(data.jumlah_file ?? 0);
|
|
|
|
let uploadDikunci = false;
|
|
|
|
let warningUpload = '';
|
|
|
|
const tglMulai =
|
|
data.tgl_mulai_pengobatan ?
|
|
new Date(data.tgl_mulai_pengobatan) :
|
|
null;
|
|
|
|
const hariIni = new Date();
|
|
|
|
let bulanBerjalan = 0;
|
|
|
|
if (tglMulai) {
|
|
|
|
bulanBerjalan =
|
|
(hariIni.getFullYear() - tglMulai.getFullYear()) * 12 +
|
|
(hariIni.getMonth() - tglMulai.getMonth());
|
|
|
|
}
|
|
|
|
// gagal
|
|
if (statusPengobatan === 'Gagal') {
|
|
|
|
uploadDikunci = true;
|
|
|
|
warningUpload =
|
|
'Upload file tidak tersedia karena pasien gagal pengobatan.';
|
|
}
|
|
|
|
// meninggal
|
|
else if (statusPengobatan === 'Meninggal') {
|
|
|
|
uploadDikunci = true;
|
|
|
|
warningUpload =
|
|
'Upload file tidak tersedia karena pasien telah meninggal.';
|
|
}
|
|
|
|
// upload pertama sudah ada
|
|
else if (jumlahFile === 1) {
|
|
|
|
if (bulanBerjalan < 2) {
|
|
|
|
uploadDikunci = true;
|
|
|
|
warningUpload =
|
|
'Upload berikutnya dapat dilakukan setelah pasien menjalani pengobatan 2 bulan.';
|
|
}
|
|
}
|
|
|
|
// upload kedua sudah ada
|
|
else if (jumlahFile === 2) {
|
|
|
|
if (bulanBerjalan < 5) {
|
|
|
|
uploadDikunci = true;
|
|
|
|
warningUpload =
|
|
'Upload berikutnya dapat dilakukan setelah pasien menjalani pengobatan 5 bulan.';
|
|
}
|
|
}
|
|
|
|
// sudah 3 file
|
|
else if (jumlahFile >= 3) {
|
|
|
|
uploadDikunci = true;
|
|
|
|
warningUpload =
|
|
'Upload file sudah mencapai batas maksimal 3 kali.';
|
|
}
|
|
|
|
return `
|
|
|
|
<div class="riwayat-item"
|
|
style="
|
|
border:1px solid #eee;
|
|
border-radius:16px;
|
|
padding:20px;
|
|
margin-bottom:20px;
|
|
background:#fafafa;
|
|
">
|
|
|
|
<div style="
|
|
display:flex;
|
|
justify-content:space-between;
|
|
align-items:center;
|
|
margin-bottom:15px;
|
|
">
|
|
|
|
<h4 style="color:#111827;">
|
|
Pengobatan Ke ${index + 1}
|
|
</h4>
|
|
|
|
<button type="button"
|
|
class="btn-hapus-riwayat"
|
|
onclick="hapusRiwayat(this)"
|
|
style="
|
|
background:#fee2e2;
|
|
color:#c40000;
|
|
border:none;
|
|
padding:8px 12px;
|
|
border-radius:8px;
|
|
cursor:pointer;
|
|
font-weight:600;
|
|
">
|
|
Hapus
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<input type="hidden"
|
|
name="riwayat[${index}][id_medis]"
|
|
value="${data.id_medis ?? ''}">
|
|
|
|
<input type="hidden"
|
|
class="jumlah-file"
|
|
value="${jumlahFile}">
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Diagnosa</label>
|
|
|
|
<select name="riwayat[${index}][diagnosa]" required>
|
|
|
|
<option value="TBC Paru"
|
|
${data.diagnosa == 'TBC Paru' ? 'selected' : ''}>
|
|
TBC Paru
|
|
</option>
|
|
|
|
<option value="TBC Ekstra Paru"
|
|
${data.diagnosa == 'TBC Ekstra Paru' ? 'selected' : ''}>
|
|
TBC Ekstra Paru
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Jam Minum Obat</label>
|
|
|
|
<input type="time"
|
|
name="riwayat[${index}][jam_minum]"
|
|
value="${data.jam_minum ?? ''}" required>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Tanggal Mulai Pengobatan</label>
|
|
|
|
<input type="date"
|
|
name="riwayat[${index}][tgl_mulai]" required
|
|
max="${today}"
|
|
value="${data.tgl_mulai_pengobatan ?? ''}"
|
|
onchange="hitungSelesaiRiwayat(this)">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Tanggal Selesai</label>
|
|
|
|
<input type="date"
|
|
name="riwayat[${index}][tgl_selesai]" required
|
|
value="${data.tgl_estimasi_selesai ?? ''}"
|
|
readonly
|
|
style="background:#f3f4f6;">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Status Pengobatan</label>
|
|
|
|
<select
|
|
name="riwayat[${index}][status_kesehatan]" required
|
|
class="status-pengobatan-select"
|
|
onchange="validasiStatusSembuh(this)">
|
|
|
|
<option value="Masih Proses"
|
|
${(data.status_kesehatan ?? 'Masih Proses') == 'Masih Proses' ? 'selected' : ''}>
|
|
Masih Proses
|
|
</option>
|
|
|
|
<option value="Sembuh"
|
|
${data.status_kesehatan == 'Sembuh' ? 'selected' : ''}>
|
|
Sembuh
|
|
</option>
|
|
|
|
<option value="Gagal"
|
|
${data.status_kesehatan == 'Gagal' ? 'selected' : ''}>
|
|
Gagal
|
|
</option>
|
|
|
|
<option value="Meninggal"
|
|
${data.status_kesehatan == 'Meninggal' ? 'selected' : ''}>
|
|
Meninggal
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- ========================= -->
|
|
<!-- HASIL LAB -->
|
|
<!-- ========================= -->
|
|
|
|
<div style="
|
|
margin-top:25px;
|
|
border-top:1px dashed #d1d5db;
|
|
padding-top:20px;
|
|
">
|
|
|
|
${data.mode === 'create' ? `
|
|
|
|
<div class="form-group">
|
|
|
|
<label>File Hasil Laboratorium <span style="color:red">*</span></label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-awal file-pasien-input"
|
|
name="riwayat[${index}][file_awal]"
|
|
accept=".pdf,.jpg,.jpeg,.png"
|
|
required>
|
|
|
|
<small class="status-file-awal"></small>
|
|
|
|
</div>
|
|
|
|
` : `
|
|
|
|
<div class="form-group">
|
|
|
|
<label>File Sebelum Pengobatan</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-awal file-pasien-input"
|
|
name="riwayat[${index}][file_awal]"
|
|
accept=".pdf,.jpg,.jpeg,.png">
|
|
|
|
<small class="status-file-awal"></small>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>File Setelah 56 Hari</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-56 file-pasien-input"
|
|
name="riwayat[${index}][file_56_hari]"
|
|
accept=".pdf,.jpg,.jpeg,.png">
|
|
|
|
<small class="status-file-56"></small>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>File Setelah 168 Hari</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-168 file-pasien-input"
|
|
name="riwayat[${index}][file_168_hari]"
|
|
accept=".pdf,.jpg,.jpeg,.png">
|
|
|
|
<small class="status-file-168"></small>
|
|
|
|
</div>
|
|
|
|
`}
|
|
|
|
</div>
|
|
|
|
<input
|
|
type="hidden"
|
|
class="jumlah-file"
|
|
value="${data?.jumlah_file ?? 0}">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function validasiStatusSembuh(selectElement) {
|
|
|
|
const parent =
|
|
selectElement.closest('.riwayat-item, .pengobatan-item');
|
|
|
|
const tglMulaiInput =
|
|
parent?.querySelector('.tgl-mulai-input');
|
|
|
|
const status =
|
|
selectElement.value;
|
|
|
|
/*
|
|
==========================================
|
|
VALIDASI SAAT USER MEMILIH SEMBUH
|
|
==========================================
|
|
*/
|
|
|
|
if (
|
|
status === 'Sembuh' &&
|
|
tglMulaiInput &&
|
|
tglMulaiInput.value
|
|
) {
|
|
|
|
const mulai =
|
|
new Date(tglMulaiInput.value);
|
|
|
|
const sekarang =
|
|
new Date();
|
|
|
|
const hari =
|
|
Math.floor(
|
|
(sekarang - mulai) / 86400000
|
|
);
|
|
|
|
if (hari < 168) {
|
|
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Tidak Dapat Mengubah Status',
|
|
text: 'Tidak bisa mengganti status menjadi sembuh karena pasien masih belum selesai menjalani pengobatan.',
|
|
width: '420px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
selectElement.value = 'Masih Proses';
|
|
}
|
|
}
|
|
|
|
handleStatusUpload(selectElement);
|
|
}
|
|
|
|
function tambahRiwayatPengobatan(data = {}) {
|
|
|
|
const container =
|
|
document.getElementById('containerRiwayatPengobatan');
|
|
|
|
const index =
|
|
container.querySelectorAll('.riwayat-item').length;
|
|
|
|
container.insertAdjacentHTML(
|
|
'beforeend',
|
|
generateRiwayatForm(index, data)
|
|
);
|
|
|
|
updateButtonHapusRiwayat();
|
|
|
|
lucide.createIcons();
|
|
|
|
setTimeout(() => {
|
|
|
|
const wrapper =
|
|
container.lastElementChild;
|
|
|
|
if (wrapper) {
|
|
|
|
updateUploadTahap(wrapper);
|
|
|
|
}
|
|
|
|
}, 100);
|
|
}
|
|
|
|
function hapusRiwayat(btn) {
|
|
|
|
btn.closest('.riwayat-item').remove();
|
|
|
|
resetNomorRiwayat();
|
|
|
|
updateButtonHapusRiwayat();
|
|
}
|
|
|
|
function resetNomorRiwayat() {
|
|
|
|
document.querySelectorAll('.riwayat-item')
|
|
.forEach((item, index) => {
|
|
|
|
item.querySelector('h4').innerText =
|
|
'Pengobatan Ke ' + (index + 1);
|
|
|
|
item.querySelectorAll('input, select')
|
|
.forEach(el => {
|
|
|
|
if (el.name.includes('[id_medis]')) {
|
|
el.name = `riwayat[${index}][id_medis]`;
|
|
}
|
|
|
|
if (el.name.includes('[diagnosa]')) {
|
|
el.name = `riwayat[${index}][diagnosa]`;
|
|
}
|
|
|
|
if (el.name.includes('[jam_minum]')) {
|
|
el.name = `riwayat[${index}][jam_minum]`;
|
|
}
|
|
|
|
if (el.name.includes('[tgl_mulai]')) {
|
|
el.name = `riwayat[${index}][tgl_mulai]`;
|
|
}
|
|
|
|
if (el.name.includes('[tgl_selesai]')) {
|
|
el.name = `riwayat[${index}][tgl_selesai]`;
|
|
}
|
|
|
|
|
|
if (el.name.includes('[file_awal]')) {
|
|
el.name = `riwayat[${index}][file_awal]`;
|
|
}
|
|
|
|
if (el.name.includes('[file_56_hari]')) {
|
|
el.name = `riwayat[${index}][file_56_hari]`;
|
|
}
|
|
|
|
if (el.name.includes('[file_168_hari]')) {
|
|
el.name = `riwayat[${index}][file_168_hari]`;
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function updateButtonHapusRiwayat() {
|
|
|
|
const items =
|
|
document.querySelectorAll('.riwayat-item');
|
|
|
|
items.forEach(item => {
|
|
|
|
const btn =
|
|
item.querySelector('.btn-hapus-riwayat');
|
|
|
|
if (btn) {
|
|
btn.style.display = 'none';
|
|
}
|
|
|
|
});
|
|
|
|
if (items.length > 1) {
|
|
|
|
const lastItem =
|
|
items[items.length - 1];
|
|
|
|
const lastBtn =
|
|
lastItem.querySelector('.btn-hapus-riwayat');
|
|
|
|
if (lastBtn) {
|
|
lastBtn.style.display = 'inline-block';
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function hitungSelesaiRiwayat(el) {
|
|
|
|
const mulai = el.value;
|
|
|
|
if (!mulai) return;
|
|
|
|
const wrapper = el.closest('.riwayat-item');
|
|
|
|
const selesai = wrapper.querySelector('input[name*="[tgl_selesai]"]');
|
|
|
|
if (!selesai) return;
|
|
|
|
const date = parseDateSafe(mulai);
|
|
|
|
date.setDate(date.getDate() + 167);
|
|
|
|
selesai.value = date.toISOString().split('T')[0];
|
|
}
|
|
</script>
|
|
|
|
@if(session('success'))
|
|
<script>
|
|
Swal.fire({
|
|
title: 'Berhasil!',
|
|
text: "{{ session('success') }}",
|
|
icon: 'success',
|
|
width: '400px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
</script>
|
|
@endif
|
|
|
|
@if(session('error'))
|
|
<script>
|
|
Swal.fire({
|
|
title: 'Gagal!',
|
|
text: "{{ session('error') }}",
|
|
icon: 'error',
|
|
width: '400px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
</script>
|
|
@endif
|
|
|
|
<script>
|
|
// ===============================
|
|
// PINDAH FASYANKES
|
|
// ===============================
|
|
|
|
const modalPindah = document.getElementById('modalPindahFasyankes');
|
|
|
|
function openPindahFasyankes(id, nama, fasyankesLama) {
|
|
|
|
document.getElementById('pindah_id_user').value = id;
|
|
document.getElementById('pindah_nama').value = nama;
|
|
document.getElementById('pindah_fasyankes_lama').value = fasyankesLama ?? '-';
|
|
|
|
document.getElementById('pindah_fasyankes_baru').value = '';
|
|
|
|
modalPindah.style.display = 'flex';
|
|
|
|
lucide.createIcons();
|
|
}
|
|
|
|
function closeModalPindah() {
|
|
modalPindah.style.display = 'none';
|
|
}
|
|
|
|
document.getElementById('formPindahFasyankes')
|
|
.addEventListener('submit', function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
const id_user = document.getElementById('pindah_id_user').value;
|
|
const nama_fasyankes = document.getElementById('pindah_fasyankes_baru').value;
|
|
|
|
if (!nama_fasyankes) {
|
|
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Pilih Fasyankes',
|
|
text: 'Silakan pilih tujuan fasyankes.',
|
|
width: '360px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
fetch(`/pindah-fasyankes/${id_user}`, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document
|
|
.querySelector('meta[name="csrf-token"]')
|
|
.getAttribute('content')
|
|
},
|
|
|
|
body: JSON.stringify({
|
|
nama_fasyankes: nama_fasyankes
|
|
})
|
|
|
|
})
|
|
.then(res => res.json())
|
|
.then(res => {
|
|
|
|
if (!res.success) {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Gagal',
|
|
text: res.message || 'Gagal memindahkan pasien.',
|
|
width: '360px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil',
|
|
text: 'Pasien berhasil dipindahkan.',
|
|
timer: 1500,
|
|
showConfirmButton: false,
|
|
width: '360px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal'
|
|
}
|
|
}).then(() => {
|
|
|
|
location.reload();
|
|
|
|
});
|
|
|
|
})
|
|
.catch(() => {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Terjadi kesalahan server.',
|
|
width: '360px',
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// =====================================
|
|
// DINAMIS RIWAYAT PENGOBATAN
|
|
// =====================================
|
|
|
|
function tambahFormPengobatan(data = null) {
|
|
|
|
const container =
|
|
document.getElementById('containerRiwayatPengobatan');
|
|
|
|
const items =
|
|
container.querySelectorAll('.pengobatan-item');
|
|
|
|
const currentIndex = items.length;
|
|
|
|
const nomorPengobatan = currentIndex + 1;
|
|
|
|
console.log(
|
|
'Jumlah pengobatan:',
|
|
currentIndex,
|
|
'Nomor:',
|
|
nomorPengobatan
|
|
);
|
|
/*
|
|
==========================================================
|
|
DATA FILE
|
|
==========================================================
|
|
*/
|
|
|
|
const jumlahFile =
|
|
data?.jumlah_file ?? 0;
|
|
|
|
const sudahUploadFile =
|
|
jumlahFile > 0;
|
|
|
|
const html = `
|
|
|
|
<div class="pengobatan-item"
|
|
style="
|
|
border:1px solid #eee;
|
|
border-radius:16px;
|
|
padding:18px;
|
|
margin-bottom:18px;
|
|
background:#fafafa;
|
|
">
|
|
|
|
<input type="hidden"
|
|
name="riwayat[${currentIndex}][id_medis]"
|
|
value="${data?.id_medis ?? ''}">
|
|
|
|
<!-- STATUS FILE -->
|
|
<input type="hidden"
|
|
class="jumlah-file"
|
|
value="${jumlahFile}">
|
|
|
|
<input type="hidden"
|
|
class="sudah-upload-file"
|
|
value="${sudahUploadFile ? '1' : '0'}">
|
|
|
|
<div style="
|
|
display:flex;
|
|
justify-content:space-between;
|
|
align-items:center;
|
|
margin-bottom:15px;
|
|
">
|
|
|
|
<h5 style="
|
|
font-size:15px;
|
|
color:#111;
|
|
font-weight:700;
|
|
">
|
|
Pengobatan Ke ${nomorPengobatan}
|
|
</h5>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-hapus-pengobatan"
|
|
onclick="hapusPengobatan(this)"
|
|
style="
|
|
display:none;
|
|
background:#fee2e2;
|
|
color:#c40000;
|
|
border:none;
|
|
padding:8px 12px;
|
|
border-radius:8px;
|
|
cursor:pointer;
|
|
font-weight:600;
|
|
">
|
|
Hapus
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Diagnosa</label>
|
|
|
|
<select
|
|
name="riwayat[${currentIndex}][diagnosa]" required
|
|
class="diagnosa-select">
|
|
|
|
<option value="TBC Paru">
|
|
TBC Paru
|
|
</option>
|
|
|
|
<option value="TBC Ekstra Paru">
|
|
TBC Ekstra Paru
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Jam Minum Obat</label>
|
|
|
|
<input type="time"
|
|
name="riwayat[${currentIndex}][jam_minum]" required
|
|
class="jam-minum-input">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Tanggal Mulai Pengobatan</label>
|
|
|
|
<input type="date"
|
|
name="riwayat[${currentIndex}][tgl_mulai]" required
|
|
max="${today}"
|
|
class="tgl-mulai-input"
|
|
onchange="hitungTanggalSelesaiItem(this)">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Estimasi Selesai (168 Hari)</label>
|
|
|
|
<input type="date"
|
|
name="riwayat[${currentIndex}][tgl_selesai]" required
|
|
class="tgl-selesai-input"
|
|
readonly
|
|
style="background:#f1f5f9;">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Status Pengobatan</label>
|
|
|
|
<select
|
|
name="riwayat[${currentIndex}][status_kesehatan]" required
|
|
class="status-pengobatan-select"
|
|
onchange="validasiStatusSembuh(this)">
|
|
|
|
<option value="Masih Proses"
|
|
${(data?.status_kesehatan ?? 'Masih Proses') == 'Masih Proses' ? 'selected' : ''}>
|
|
Masih Proses
|
|
</option>
|
|
|
|
<option value="Sembuh"
|
|
${data?.status_kesehatan == 'Sembuh' ? 'selected' : ''}>
|
|
Sembuh
|
|
</option>
|
|
|
|
<option value="Gagal"
|
|
${data?.status_kesehatan == 'Gagal' ? 'selected' : ''}>
|
|
Gagal
|
|
</option>
|
|
|
|
<option value="Meninggal"
|
|
${data?.status_kesehatan == 'Meninggal' ? 'selected' : ''}>
|
|
Meninggal
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- ========================= -->
|
|
<!-- UPLOAD HASIL LAB -->
|
|
<!-- ========================= -->
|
|
|
|
<div style="
|
|
margin-top:25px;
|
|
border-top:1px dashed #d1d5db;
|
|
padding-top:20px;
|
|
">
|
|
|
|
<h5 style="
|
|
color:#c40000;
|
|
margin-bottom:15px;
|
|
font-size:15px;
|
|
font-weight:700;
|
|
">
|
|
Upload Hasil Laboratorium
|
|
</h5>
|
|
|
|
${data?.mode === 'create' ? `
|
|
|
|
<div class="form-group">
|
|
|
|
<label>
|
|
File Hasil Laboratorium
|
|
<span style="color:red">*</span>
|
|
</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-awal file-pasien-input"
|
|
name="riwayat[${currentIndex}][file_awal]"
|
|
accept=".pdf,.jpg,.jpeg,.png"
|
|
required>
|
|
|
|
</div>
|
|
|
|
` : `
|
|
|
|
<div class="form-group">
|
|
|
|
<label>
|
|
File Sebelum Pengobatan
|
|
</label>
|
|
|
|
<div class="upload-wrapper">
|
|
|
|
<input
|
|
type="file"
|
|
class="file-awal file-pasien-input"
|
|
name="riwayat[${currentIndex}][file_awal]"
|
|
data-has-file="${data?.file_awal ? '1' : '0'}"
|
|
onchange="konfirmasiUploadUlang(this)">
|
|
|
|
<input
|
|
type="hidden"
|
|
name="riwayat[${currentIndex}][file_awal_lama]"
|
|
value="${data?.file_awal ?? ''}">
|
|
|
|
<small class="file-info">
|
|
${
|
|
data?.file_awal
|
|
? 'File hasil laboratorium sudah tersimpan'
|
|
: 'Belum ada file'
|
|
}
|
|
</small>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>
|
|
File Setelah 56 Hari
|
|
</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-56 file-pasien-input"
|
|
name="riwayat[${currentIndex}][file_56_hari]"
|
|
data-has-file="${data?.file_56_hari ? '1' : '0'}"
|
|
onchange="konfirmasiUploadUlang(this)">
|
|
|
|
<input
|
|
type="hidden"
|
|
name="riwayat[${currentIndex}][file_56_hari_lama]"
|
|
value="${data?.file_56_hari ?? ''}">
|
|
|
|
<small class="file-info">
|
|
${
|
|
data?.file_56_hari
|
|
? 'File hasil laboratorium sudah tersimpan'
|
|
: 'Belum ada file'
|
|
}
|
|
</small>
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>
|
|
File Setelah 168 Hari
|
|
</label>
|
|
|
|
<input
|
|
type="file"
|
|
class="file-168 file-pasien-input"
|
|
name="riwayat[${currentIndex}][file_168_hari]"
|
|
data-has-file="${data?.file_168_hari ? '1' : '0'}"
|
|
onchange="konfirmasiUploadUlang(this)">
|
|
|
|
<input
|
|
type="hidden"
|
|
name="riwayat[${currentIndex}][file_168_hari_lama]"
|
|
value="${data?.file_168_hari ?? ''}">
|
|
|
|
<small class="file-info">
|
|
${
|
|
data?.file_168_hari
|
|
? 'File hasil laboratorium sudah tersimpan'
|
|
: 'Belum ada file'
|
|
}
|
|
</small>
|
|
|
|
</div>
|
|
|
|
`}
|
|
|
|
<input
|
|
type="hidden"
|
|
class="jumlah-file"
|
|
value="${data?.jumlah_file ?? 0}">
|
|
|
|
</div>
|
|
|
|
<input type="hidden"
|
|
class="jumlah-file"
|
|
value="${data?.jumlah_file ?? 0}">
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
`;
|
|
|
|
container.insertAdjacentHTML('beforeend', html);
|
|
|
|
lucide.createIcons();
|
|
|
|
if (data) {
|
|
|
|
const terakhir =
|
|
container.lastElementChild;
|
|
|
|
terakhir.querySelector('.diagnosa-select').value =
|
|
data.diagnosa || 'TBC Paru';
|
|
|
|
terakhir.querySelector('.jam-minum-input').value =
|
|
data.jam_minum || '';
|
|
|
|
terakhir.querySelector('.tgl-mulai-input').value =
|
|
data.tgl_mulai_pengobatan || '';
|
|
|
|
terakhir.querySelector('.tgl-selesai-input').value =
|
|
data.tgl_estimasi_selesai || '';
|
|
|
|
const statusSelect =
|
|
terakhir.querySelector('.status-pengobatan-select');
|
|
|
|
if (statusSelect) {
|
|
|
|
statusSelect.value =
|
|
data.status_kesehatan || 'Masih Proses';
|
|
|
|
handleStatusUpload(statusSelect);
|
|
}
|
|
}
|
|
|
|
updateButtonHapusPengobatan();
|
|
}
|
|
|
|
|
|
function hapusPengobatan(button) {
|
|
|
|
const items =
|
|
document.querySelectorAll(
|
|
'.pengobatan-item'
|
|
);
|
|
|
|
if (items.length <= 1) {
|
|
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Tidak Bisa Dihapus',
|
|
text: 'Pengobatan pertama wajib ada.'
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
button.closest('.pengobatan-item').remove();
|
|
|
|
updateNomorPengobatan();
|
|
|
|
updateButtonHapusPengobatan();
|
|
}
|
|
|
|
function updateButtonHapusPengobatan() {
|
|
|
|
const items =
|
|
document.querySelectorAll('.pengobatan-item');
|
|
|
|
items.forEach((item, index) => {
|
|
|
|
const btn =
|
|
item.querySelector('.btn-hapus-pengobatan');
|
|
|
|
if (!btn) return;
|
|
|
|
// Pengobatan pertama tidak boleh dihapus
|
|
if (index === 0) {
|
|
|
|
btn.style.display = 'none';
|
|
|
|
return;
|
|
}
|
|
|
|
// Hanya pengobatan terakhir yang bisa dihapus
|
|
btn.style.display =
|
|
index === items.length - 1 ?
|
|
'flex' :
|
|
'none';
|
|
|
|
});
|
|
}
|
|
|
|
function updateNomorPengobatan() {
|
|
|
|
const items = document.querySelectorAll('.pengobatan-item');
|
|
|
|
items.forEach((item, index) => {
|
|
|
|
item.querySelector('h5').innerText =
|
|
`Pengobatan Ke ${index + 1}`;
|
|
|
|
// update ulang semua name input
|
|
item.querySelectorAll('input, select').forEach(el => {
|
|
|
|
if (el.name.includes('[id_medis]')) {
|
|
el.name = `riwayat[${index}][id_medis]`;
|
|
}
|
|
|
|
if (el.name.includes('[diagnosa]')) {
|
|
el.name = `riwayat[${index}][diagnosa]`;
|
|
}
|
|
|
|
if (el.name.includes('[jam_minum]')) {
|
|
el.name = `riwayat[${index}][jam_minum]`;
|
|
}
|
|
|
|
if (el.name.includes('[tgl_mulai]')) {
|
|
el.name = `riwayat[${index}][tgl_mulai]`;
|
|
}
|
|
|
|
if (el.name.includes('[status_kesehatan]')) {
|
|
el.name = `riwayat[${index}][status_kesehatan]`;
|
|
}
|
|
|
|
if (el.name.includes('[file_awal]')) {
|
|
el.name = `riwayat[${index}][file_awal]`;
|
|
}
|
|
|
|
if (el.name.includes('[file_56_hari]')) {
|
|
el.name = `riwayat[${index}][file_56_hari]`;
|
|
}
|
|
|
|
if (el.name.includes('[file_168_hari]')) {
|
|
el.name = `riwayat[${index}][file_168_hari]`;
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function handleStatusUpload(selectElement) {
|
|
|
|
const parent =
|
|
selectElement.closest('.riwayat-item, .pengobatan-item');
|
|
|
|
if (!parent) return;
|
|
|
|
const fileAwal =
|
|
parent.querySelector('.file-awal');
|
|
|
|
const file56 =
|
|
parent.querySelector('.file-56');
|
|
|
|
const file168 =
|
|
parent.querySelector('.file-168');
|
|
|
|
const tglMulaiInput =
|
|
parent.querySelector('.tgl-mulai-input');
|
|
|
|
const status =
|
|
selectElement.value;
|
|
/*
|
|
==========================================
|
|
STATUS GAGAL / MENINGGAL
|
|
==========================================
|
|
*/
|
|
|
|
if (
|
|
status === 'Gagal' ||
|
|
status === 'Meninggal'
|
|
) {
|
|
|
|
disableFile(fileAwal);
|
|
disableFile(file56);
|
|
disableFile(file168);
|
|
|
|
updateFileInfo(parent, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================
|
|
BELUM ADA TANGGAL MULAI
|
|
==========================================
|
|
*/
|
|
|
|
if (!tglMulaiInput || !tglMulaiInput.value) {
|
|
|
|
enableFile(fileAwal);
|
|
|
|
disableFile(file56);
|
|
disableFile(file168);
|
|
|
|
updateFileInfo(parent, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
const mulai =
|
|
new Date(tglMulaiInput.value);
|
|
|
|
const sekarang =
|
|
new Date();
|
|
|
|
const hari =
|
|
Math.floor(
|
|
(sekarang - mulai) / 86400000
|
|
);
|
|
|
|
enableFile(fileAwal);
|
|
|
|
if (hari >= 56) {
|
|
enableFile(file56);
|
|
} else {
|
|
disableFile(file56);
|
|
}
|
|
|
|
if (hari >= 168) {
|
|
enableFile(file168);
|
|
} else {
|
|
disableFile(file168);
|
|
}
|
|
|
|
updateFileInfo(parent, hari);
|
|
}
|
|
|
|
function updateFileInfo(parent, hari) {
|
|
|
|
const infoAwal =
|
|
parent.querySelector('.file-awal')
|
|
?.closest('.form-group')
|
|
?.querySelector('.file-info');
|
|
|
|
const info56 =
|
|
parent.querySelector('.file-56')
|
|
?.closest('.form-group')
|
|
?.querySelector('.file-info');
|
|
|
|
const info168 =
|
|
parent.querySelector('.file-168')
|
|
?.closest('.form-group')
|
|
?.querySelector('.file-info');
|
|
|
|
const fileAwalLama =
|
|
parent.querySelector(
|
|
'input[name*="[file_awal_lama]"]'
|
|
)?.value;
|
|
|
|
const file56Lama =
|
|
parent.querySelector(
|
|
'input[name*="[file_56_hari_lama]"]'
|
|
)?.value;
|
|
|
|
const file168Lama =
|
|
parent.querySelector(
|
|
'input[name*="[file_168_hari_lama]"]'
|
|
)?.value;
|
|
|
|
/*
|
|
==========================================
|
|
FILE AWAL
|
|
==========================================
|
|
*/
|
|
|
|
if (infoAwal) {
|
|
|
|
if (fileAwalLama) {
|
|
|
|
infoAwal.innerText =
|
|
'File hasil laboratorium sudah tersimpan';
|
|
|
|
} else {
|
|
|
|
infoAwal.innerText =
|
|
'File hasil laboratorium';
|
|
}
|
|
}
|
|
|
|
/*
|
|
==========================================
|
|
FILE 56 HARI
|
|
==========================================
|
|
*/
|
|
|
|
if (info56) {
|
|
|
|
if (file56Lama) {
|
|
|
|
info56.innerText =
|
|
'File hasil laboratorium sudah tersimpan';
|
|
|
|
} else if (hari < 56) {
|
|
|
|
info56.innerText =
|
|
`Belum waktunya upload (menunggu hari ke-56)`;
|
|
|
|
} else {
|
|
|
|
info56.innerText =
|
|
'File hasil laboratorium';
|
|
}
|
|
}
|
|
|
|
/*
|
|
==========================================
|
|
FILE 168 HARI
|
|
==========================================
|
|
*/
|
|
|
|
if (info168) {
|
|
|
|
if (file168Lama) {
|
|
|
|
info168.innerText =
|
|
'File hasil laboratorium sudah tersimpan';
|
|
|
|
} else if (hari < 168) {
|
|
|
|
info168.innerText =
|
|
`Belum waktunya upload (menunggu hari ke-168)`;
|
|
|
|
} else {
|
|
|
|
info168.innerText =
|
|
'File hasil laboratorium';
|
|
}
|
|
}
|
|
}
|
|
|
|
function konfirmasiUploadUlang(input) {
|
|
|
|
const hasFile =
|
|
input.dataset.hasFile === '1';
|
|
|
|
if (!hasFile) return;
|
|
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Upload Ulang File?',
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
File hasil laboratorium yang lama akan digantikan dengan file baru.
|
|
</div>
|
|
`,
|
|
width: '360px',
|
|
showCancelButton: true,
|
|
reverseButtons: true,
|
|
focusCancel: true,
|
|
allowOutsideClick: false,
|
|
|
|
confirmButtonText: `
|
|
<div style="
|
|
display:flex;
|
|
align-items:center;
|
|
justify-content:center;
|
|
gap:6px;
|
|
">
|
|
<i data-lucide="refresh-cw"
|
|
style="width:16px;height:16px;">
|
|
</i>
|
|
<span>Upload Ulang</span>
|
|
</div>
|
|
`,
|
|
|
|
cancelButtonText: `
|
|
<div style="
|
|
display:flex;
|
|
align-items:center;
|
|
justify-content:center;
|
|
gap:6px;
|
|
">
|
|
<i data-lucide="x"
|
|
style="width:16px;height:16px;">
|
|
</i>
|
|
<span>Batal</span>
|
|
</div>
|
|
`,
|
|
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal',
|
|
cancelButton: 'btn-cancel-swal'
|
|
},
|
|
|
|
didOpen: () => {
|
|
lucide.createIcons();
|
|
}
|
|
|
|
}).then(result => {
|
|
|
|
if (!result.isConfirmed) {
|
|
|
|
input.value = '';
|
|
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
function enableFile(input) {
|
|
|
|
if (!input) return;
|
|
|
|
input.disabled = false;
|
|
input.style.background = '';
|
|
input.style.cursor = '';
|
|
input.style.opacity = '1';
|
|
}
|
|
|
|
function disableFile(input) {
|
|
|
|
if (!input) return;
|
|
|
|
input.disabled = true;
|
|
input.style.background = '#f3f4f6';
|
|
input.style.cursor = 'not-allowed';
|
|
input.style.opacity = '0.6';
|
|
}
|
|
|
|
function hitungTanggalSelesaiItem(input) {
|
|
|
|
const item = input.closest('.pengobatan-item');
|
|
|
|
const selesaiInput = item.querySelector('.tgl-selesai-input');
|
|
|
|
if (!input.value) {
|
|
|
|
selesaiInput.value = '';
|
|
|
|
return;
|
|
}
|
|
|
|
const date = new Date(input.value);
|
|
|
|
date.setDate(date.getDate() + 167);
|
|
|
|
selesaiInput.value =
|
|
date.toISOString().split('T')[0];
|
|
}
|
|
|
|
document.addEventListener('change', function(e) {
|
|
|
|
/*
|
|
==========================================================
|
|
VALIDASI FILE HASIL LAB
|
|
==========================================================
|
|
*/
|
|
|
|
if (e.target.classList.contains('file-pasien-input')) {
|
|
|
|
const maxSize = 5 * 1024 * 1024; // 5 MB
|
|
|
|
const file = e.target.files[0];
|
|
|
|
/*
|
|
==========================================================
|
|
CARI / BUAT WARNING TEXT
|
|
==========================================================
|
|
*/
|
|
|
|
let warningText =
|
|
e.target.parentElement.querySelector('.upload-warning');
|
|
|
|
if (!warningText) {
|
|
|
|
warningText = document.createElement('small');
|
|
|
|
warningText.classList.add('upload-warning');
|
|
|
|
warningText.style.display = 'block';
|
|
warningText.style.marginTop = '8px';
|
|
warningText.style.fontSize = '13px';
|
|
warningText.style.fontWeight = '600';
|
|
warningText.style.color = '#dc2626';
|
|
|
|
e.target.parentElement.appendChild(warningText);
|
|
}
|
|
|
|
/*
|
|
==========================================================
|
|
RESET WARNING
|
|
==========================================================
|
|
*/
|
|
|
|
warningText.innerHTML = '';
|
|
|
|
/*
|
|
==========================================================
|
|
VALIDASI FILE
|
|
==========================================================
|
|
*/
|
|
|
|
if (file && file.size > maxSize) {
|
|
|
|
warningText.innerHTML =
|
|
'File gagal diupload karena ukuran melebihi batas maksimal 5 MB.';
|
|
|
|
e.target.value = '';
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================
|
|
VALIDASI FORMAT FILE
|
|
==========================================================
|
|
*/
|
|
|
|
const allowedTypes = [
|
|
'application/pdf',
|
|
'image/jpeg',
|
|
'image/jpg',
|
|
'image/png'
|
|
];
|
|
|
|
if (file && !allowedTypes.includes(file.type)) {
|
|
|
|
warningText.innerHTML =
|
|
'Format file tidak didukung. Gunakan PDF, JPG, JPEG, atau PNG.';
|
|
|
|
e.target.value = '';
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
==========================================================
|
|
JIKA VALID
|
|
==========================================================
|
|
*/
|
|
|
|
warningText.innerHTML = '';
|
|
}
|
|
});
|
|
|
|
/*
|
|
==========================================================
|
|
VALIDASI FORM WAJIB ISI
|
|
==========================================================
|
|
*/
|
|
|
|
document.getElementById('pasienForm')
|
|
.addEventListener('submit', function(e) {
|
|
|
|
const form = this;
|
|
|
|
let adaKosong = false;
|
|
|
|
form.querySelectorAll(
|
|
'input[required], select[required], textarea[required]'
|
|
).forEach(field => {
|
|
|
|
let kosong = false;
|
|
|
|
if (field.type === 'file') {
|
|
|
|
kosong = field.files.length === 0;
|
|
|
|
} else {
|
|
|
|
kosong = !field.value.trim();
|
|
}
|
|
|
|
if (!field.disabled && kosong) {
|
|
|
|
adaKosong = true;
|
|
|
|
field.style.border =
|
|
'2px solid #dc2626';
|
|
|
|
} else {
|
|
|
|
field.style.border = '';
|
|
}
|
|
});
|
|
|
|
if (adaKosong) {
|
|
|
|
e.preventDefault();
|
|
|
|
alert(
|
|
'Semua form wajib diisi termasuk upload file hasil laboratorium.'
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
});
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
});
|
|
|
|
function refreshIcons() {
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
}
|
|
document.addEventListener("click", function(e) {
|
|
|
|
const btn = e.target.closest(".btn-edit-pasien");
|
|
|
|
if (!btn) return;
|
|
|
|
prepareEdit(btn.dataset.item);
|
|
|
|
});
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
</html> |