2396 lines
65 KiB
PHP
2396 lines
65 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="id">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Skrining 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: .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 */
|
|
.top-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.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;
|
|
color: #888;
|
|
z-index: 9;
|
|
}
|
|
|
|
.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;
|
|
transition: .3s;
|
|
}
|
|
|
|
.search-wrapper input:focus {
|
|
border-color: #c40000;
|
|
box-shadow: 0 0 0 3px rgba(196, 0, 0, .1);
|
|
}
|
|
|
|
/* FILTER */
|
|
.filter-accordion {
|
|
background: white;
|
|
border-radius: 15px;
|
|
margin-bottom: 25px;
|
|
box-shadow: 0 4px 15px rgba(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: .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 .3s ease-out, padding .3s ease;
|
|
background: #fff;
|
|
}
|
|
|
|
.filter-content.active {
|
|
padding: 20px 25px;
|
|
max-height: 600px;
|
|
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: 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 10px;
|
|
outline: none;
|
|
font-size: 13px;
|
|
transition: .3s;
|
|
}
|
|
|
|
.filter-group input:focus,
|
|
.filter-group select:focus {
|
|
border-color: #c40000;
|
|
box-shadow: 0 0 0 3px rgba(196, 0, 0, .08);
|
|
}
|
|
|
|
.filter-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 10px;
|
|
margin-top: 15px;
|
|
border-top: 1px dashed #eee;
|
|
padding-top: 15px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.btn-cari,
|
|
.btn-reset,
|
|
.btn-export {
|
|
padding: 8px 16px;
|
|
border-radius: 8px;
|
|
border: none;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
font-size: 12px;
|
|
transition: .3s;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.btn-cari {
|
|
background: #c40000;
|
|
color: white;
|
|
}
|
|
|
|
.btn-reset {
|
|
background: #64748b;
|
|
color: white;
|
|
}
|
|
|
|
.btn-export {
|
|
background: #22c55e;
|
|
color: white;
|
|
}
|
|
|
|
/* TABLE */
|
|
.table-container {
|
|
background: white;
|
|
border-radius: 20px;
|
|
padding: 20px;
|
|
box-shadow: 0 5px 20px rgba(0, 0, 0, .05);
|
|
width: 100%;
|
|
}
|
|
|
|
.table-scroll {
|
|
width: 100%;
|
|
overflow: visible;
|
|
}
|
|
|
|
table {
|
|
width: 100%;
|
|
table-layout: fixed;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
padding: 14px 12px;
|
|
text-align: left;
|
|
vertical-align: middle;
|
|
white-space: nowrap;
|
|
font-size: 13px;
|
|
}
|
|
|
|
thead th {
|
|
background: #fafafa;
|
|
border-bottom: 2px solid #f0f0f0;
|
|
color: #444;
|
|
font-weight: 600;
|
|
}
|
|
|
|
th.col-no,
|
|
td.col-no {
|
|
width: 60px;
|
|
}
|
|
|
|
th.col-nama,
|
|
td.col-nama {
|
|
width: 220px;
|
|
}
|
|
|
|
td,
|
|
th {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
}
|
|
|
|
tbody tr:hover td.col-no,
|
|
tbody tr:hover td.col-nama {
|
|
background-color: #f9fafb !important;
|
|
}
|
|
|
|
.badge {
|
|
padding: 6px 12px;
|
|
border-radius: 20px;
|
|
font-size: 10px;
|
|
font-weight: 700;
|
|
display: inline-block;
|
|
text-align: center;
|
|
}
|
|
|
|
.badge-danger {
|
|
background: #fee2e2;
|
|
color: #ef4444;
|
|
}
|
|
|
|
.badge-success {
|
|
background: #dcfce7;
|
|
color: #22c55e;
|
|
}
|
|
|
|
/* ACTION */
|
|
.action-group {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.btn-action {
|
|
width: 32px;
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 10px;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: .3s;
|
|
}
|
|
|
|
.btn-view-detail {
|
|
background: #f1f5f9;
|
|
color: #64748b;
|
|
}
|
|
|
|
.btn-make-patient {
|
|
background: #eff6ff;
|
|
color: #3b82f6;
|
|
}
|
|
|
|
.btn-delete-skrining {
|
|
background: #fee2e2;
|
|
color: #ef4444;
|
|
}
|
|
|
|
.btn-delete-skrining:hover {
|
|
background: #fecaca;
|
|
}
|
|
|
|
.disabled-btn {
|
|
background: #e5e7eb !important;
|
|
color: #9ca3af !important;
|
|
cursor: not-allowed !important;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
/* MODAL */
|
|
.modal-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(15, 23, 42, .45);
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
backdrop-filter: blur(6px);
|
|
padding: 18px;
|
|
}
|
|
|
|
.modal-content {
|
|
background: #ffffff;
|
|
width: 100%;
|
|
max-width: 400px;
|
|
border-radius: 22px;
|
|
overflow: hidden;
|
|
box-shadow: 0 20px 45px rgba(0, 0, 0, .16);
|
|
}
|
|
|
|
.modal-header {
|
|
padding: 15px 18px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
border-bottom: 1px solid #f1f5f9;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
font-size: 15px;
|
|
font-weight: 700;
|
|
color: #0f172a;
|
|
}
|
|
|
|
.btn-icon {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: none;
|
|
background: #f8fafc;
|
|
border-radius: 9px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
color: #64748b;
|
|
}
|
|
|
|
.modal-body {
|
|
padding: 16px;
|
|
}
|
|
|
|
.patient-info {
|
|
background: #f8fafc;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 14px;
|
|
padding: 15px;
|
|
margin-bottom: 14px;
|
|
}
|
|
|
|
.patient-label {
|
|
font-size: 10px;
|
|
font-weight: 600;
|
|
color: #c40000;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.patient-name {
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
color: #1e293b;
|
|
}
|
|
|
|
.result-card.terduga {
|
|
background: #fef2f2;
|
|
border: 1px solid #fecaca;
|
|
}
|
|
|
|
.result-card.terduga .result-title,
|
|
.result-card.terduga .result-value {
|
|
color: #dc2626;
|
|
}
|
|
|
|
.result-card.tidak-terduga {
|
|
background: #f0fdf4;
|
|
border: 1px solid #bbf7d0;
|
|
}
|
|
|
|
.result-card.tidak-terduga .result-title,
|
|
.result-card.tidak-terduga .result-value {
|
|
color: #16a34a;
|
|
}
|
|
|
|
.status-wrapper {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.kuesioner-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.q-item {
|
|
background: #f8fafc;
|
|
border-radius: 12px;
|
|
padding: 10px 12px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.q-text {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
color: #334155;
|
|
}
|
|
|
|
.q-ans {
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
padding: 5px 10px;
|
|
border-radius: 20px;
|
|
}
|
|
|
|
.text-red {
|
|
background: #fee2e2;
|
|
color: #dc2626;
|
|
}
|
|
|
|
.text-green {
|
|
background: #dcfce7;
|
|
color: #16a34a;
|
|
}
|
|
|
|
.btn-close-modal {
|
|
width: 100%;
|
|
border: none;
|
|
background: #c40000;
|
|
color: white;
|
|
padding: 10px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.pagination-wrapper-modern {
|
|
margin-top: 25px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 14px 18px;
|
|
background: #ffffff;
|
|
border-radius: 14px;
|
|
border: 1px solid #eef2f7;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, .04);
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
.pagination-info {
|
|
font-size: 12px;
|
|
color: #64748b;
|
|
}
|
|
|
|
.pagination-links-modern nav {
|
|
display: flex;
|
|
gap: 6px;
|
|
}
|
|
|
|
@media(max-width:768px) {
|
|
.sidebar {
|
|
display: none;
|
|
}
|
|
|
|
.main-content {
|
|
margin-left: 0;
|
|
width: 100%;
|
|
padding: 20px;
|
|
}
|
|
|
|
table {
|
|
width: 1300px;
|
|
}
|
|
}
|
|
|
|
.modal-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: rgba(0, 0, 0, 0.4);
|
|
display: none;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 9999;
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.modal-content {
|
|
width: 900px;
|
|
max-width: 95%;
|
|
border-radius: 20px;
|
|
overflow: hidden;
|
|
border-radius: 20px;
|
|
padding: 30px;
|
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.detail-layout {
|
|
display: grid;
|
|
grid-template-columns: 320px 1fr;
|
|
gap: 20px;
|
|
align-items: start;
|
|
}
|
|
|
|
.detail-left,
|
|
.detail-right {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.modal-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
color: #c40000;
|
|
}
|
|
|
|
.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 {
|
|
width: 100%;
|
|
padding: 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 10px;
|
|
outline: none;
|
|
font-size: 14px;
|
|
font-family: 'Poppins', sans-serif;
|
|
background: white;
|
|
}
|
|
|
|
.field-error {
|
|
border: 1px solid #dc2626 !important;
|
|
}
|
|
|
|
.field-note {
|
|
color: #dc2626;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
margin-top: 4px;
|
|
display: none;
|
|
}
|
|
|
|
.form-group input[readonly] {
|
|
background: #f9fafb;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 16px;
|
|
font-weight: 700;
|
|
margin-top: 20px;
|
|
margin-bottom: 10px;
|
|
color: #000;
|
|
}
|
|
|
|
.modal-footer {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 12px;
|
|
margin-top: 30px;
|
|
}
|
|
|
|
.btn {
|
|
padding: 12px 25px;
|
|
border-radius: 10px;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
transition: 0.2s;
|
|
}
|
|
|
|
.btn-cancel {
|
|
background: #f3f4f6;
|
|
color: #4b5563;
|
|
}
|
|
|
|
.btn-submit {
|
|
background: #c40000;
|
|
color: white;
|
|
}
|
|
|
|
.btn-submit:hover {
|
|
background: #a80000;
|
|
}
|
|
|
|
.btn-submit:disabled {
|
|
background: #9ca3af;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.close-btn {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: none;
|
|
border-radius: 10px;
|
|
background: #e8f5e9;
|
|
color: #2e7d32;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.identity-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 10px;
|
|
margin: 12px 0;
|
|
}
|
|
|
|
.identity-item,
|
|
.identity-item-full {
|
|
background: white;
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
border: 1px solid #ffffff;
|
|
min-height: 70px;
|
|
}
|
|
|
|
.identity-item span,
|
|
.identity-item-full span {
|
|
display: block;
|
|
font-size: 11px;
|
|
color: #47515f;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.identity-item strong,
|
|
.identity-item-full strong {
|
|
font-size: 13px;
|
|
color: #1e293b;
|
|
word-break: break-word;
|
|
white-space: normal;
|
|
}
|
|
|
|
.result-card {
|
|
background: #f8fafc;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 14px;
|
|
padding: 15px;
|
|
}
|
|
|
|
.result-title {
|
|
font-size: 12px;
|
|
color: #64748b;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.result-value {
|
|
font-size: 14px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.modal-footer-detail {
|
|
padding: 20px 30px;
|
|
border-top: 1px solid #f1f5f9;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.modal-footer-detail .btn-close-modal {
|
|
width: auto;
|
|
min-width: 120px;
|
|
padding: 12px 24px;
|
|
border: none;
|
|
border-radius: 12px;
|
|
background: #c40000;
|
|
color: white;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: .2s;
|
|
}
|
|
|
|
.modal-footer-detail .btn-close-modal:hover {
|
|
background: #a80000;
|
|
}
|
|
</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>
|
|
@if(session('role') !== 'super_admin')<li><a href="{{ url('/data-pasien') }}"><i data-lucide="users"></i> Data Pasien</a></li>@endif
|
|
|
|
<li class="active">
|
|
<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>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="main-content">
|
|
|
|
<div class="header-wrapper">
|
|
<h1 class="header-title">Skrining Pasien</h1>
|
|
</div>
|
|
|
|
<div class="top-bar">
|
|
|
|
<div></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...">
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- FILTER -->
|
|
<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('hasil_skrining') ||
|
|
request('fasyankes') ||
|
|
request('tgl_mulai') ||
|
|
request('tgl_selesai')
|
|
? 'active'
|
|
: ''
|
|
}}"
|
|
id="filterContent">
|
|
|
|
<form action="{{ url('/skrining') }}" method="GET" id="filterForm">
|
|
|
|
<div class="filter-grid">
|
|
|
|
<div class="filter-group">
|
|
<label>Hasil Skrining</label>
|
|
|
|
<select name="hasil_skrining" id="filter_hasil">
|
|
|
|
<option value="">Semua Hasil</option>
|
|
|
|
<option
|
|
value="Terduga TBC"
|
|
{{ request('hasil_skrining') == 'Terduga TBC' ? 'selected' : '' }}>
|
|
Terduga TBC
|
|
</option>
|
|
|
|
<option
|
|
value="Tidak Terduga TBC"
|
|
{{ request('hasil_skrining') == 'Tidak Terduga TBC' ? 'selected' : '' }}>
|
|
Tidak Terduga TBC
|
|
</option>
|
|
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group">
|
|
|
|
<label>Fasyankes</label>
|
|
|
|
<select name="fasyankes" id="filter_fasyankes">
|
|
|
|
<option value="">Semua Fasyankes</option>
|
|
|
|
@forelse($fasyankes_list ?? [] as $f)
|
|
|
|
<option
|
|
value="{{ $f->nama_fasyankes }}"
|
|
{{ request('fasyankes') == $f->nama_fasyankes ? 'selected' : '' }}>
|
|
{{ $f->nama_fasyankes }}
|
|
</option>
|
|
|
|
@empty
|
|
@endforelse
|
|
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group">
|
|
<label>Mulai Tanggal</label>
|
|
|
|
<input
|
|
type="date"
|
|
name="tgl_mulai"
|
|
id="filter_tgl_mulai"
|
|
value="{{ request('tgl_mulai') }}">
|
|
</div>
|
|
|
|
<div class="filter-group">
|
|
<label>Sampai Tanggal</label>
|
|
|
|
<input
|
|
type="date"
|
|
name="tgl_selesai"
|
|
id="filter_tgl_selesai"
|
|
value="{{ request('tgl_selesai') }}">
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="filter-actions">
|
|
|
|
<a href="{{ url('/skrining') }}" class="btn-reset">
|
|
<i data-lucide="refresh-cw" size="14"></i>
|
|
Reset
|
|
</a>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-export"
|
|
onclick="submitExport()">
|
|
<i data-lucide="download" size="14"></i>
|
|
Export
|
|
</button>
|
|
|
|
<button type="submit" class="btn-cari">
|
|
<i data-lucide="search" size="14"></i>
|
|
Cari Data
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-container">
|
|
|
|
<div class="table-scroll">
|
|
|
|
<table>
|
|
|
|
<thead>
|
|
<tr>
|
|
|
|
<th class="col-no">No</th>
|
|
<th class="col-nama">Nama</th>
|
|
<th>NIK</th>
|
|
<th>Tgl Skrining</th>
|
|
<th>Hasil Skrining</th>
|
|
|
|
@if(session('role') === 'super_admin')
|
|
<th>Fasyankes</th>
|
|
@endif
|
|
|
|
<th style="text-align:center;">Aksi</th>
|
|
|
|
</tr>
|
|
</thead>
|
|
|
|
<tbody id="skriningTableBody">
|
|
|
|
@forelse($skrining as $s)
|
|
|
|
<tr>
|
|
|
|
<td class="col-no">
|
|
{{
|
|
($skrining->currentPage() - 1)
|
|
* $skrining->perPage()
|
|
+ $loop->iteration
|
|
}}
|
|
</td>
|
|
|
|
<td class="col-nama">
|
|
{{ $s->nama_lengkap ?? '-' }}
|
|
</td>
|
|
|
|
<td>
|
|
{{ $s->nik ?? '-' }}
|
|
</td>
|
|
|
|
<td>
|
|
{{ !empty($s->tgl_skrining) ? date('d/m/Y', strtotime($s->tgl_skrining)) : '-' }}
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<span class="badge {{ ($s->hasil_skrining ?? '') == 'Terduga TBC' ? 'badge-danger' : 'badge-success' }}">
|
|
|
|
{{ $s->hasil_skrining ?? '-' }}
|
|
|
|
</span>
|
|
|
|
</td>
|
|
|
|
@if(session('role') === 'super_admin')
|
|
|
|
<td>
|
|
{{ $s->nama_fasyankes ?? '-' }}
|
|
</td>
|
|
|
|
@endif
|
|
|
|
{{-- GANTI DENGAN INI (100% TANPA JSON ERROR) --}}
|
|
|
|
<td style="text-align:center;">
|
|
|
|
<div class="action-group">
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-action btn-view-detail"
|
|
title="Lihat Detail"
|
|
data-item='@json($s)'
|
|
onclick="openSkriningFromButton(this)">
|
|
<i data-lucide="eye" size="16"></i>
|
|
</button>
|
|
|
|
@if($s->hasil_skrining == 'Terduga TBC')
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-action btn-make-patient"
|
|
title="Daftarkan Pasien"
|
|
data-item='@json($s)'
|
|
onclick="openModalJadikanPasien(this)">
|
|
<i data-lucide="user-plus" size="16"></i>
|
|
</button>
|
|
|
|
@else
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-action btn-make-patient disabled-btn"
|
|
disabled>
|
|
<i data-lucide="user-plus" size="16"></i>
|
|
</button>
|
|
|
|
@endif
|
|
|
|
@if(session('role') == 'super_admin')
|
|
|
|
<form
|
|
id="delete-form-{{ $s->id_skrining ?? $s->id }}"
|
|
action="{{ url('/skrining/hapus/' . ($s->id_skrining ?? $s->id)) }}"
|
|
method="POST"
|
|
style="display:inline;">
|
|
|
|
@csrf
|
|
@method('DELETE')
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-action btn-delete-skrining"
|
|
title="Hapus Skrining"
|
|
onclick="confirmDeleteSkrining(
|
|
'{{ $s->id_skrining ?? $s->id }}',
|
|
'{{ addslashes($s->nama_lengkap) }}'
|
|
)">
|
|
|
|
<i data-lucide="trash-2" size="16"></i>
|
|
|
|
</button>
|
|
|
|
</form>
|
|
|
|
@endif
|
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
@empty
|
|
|
|
<tr>
|
|
<td colspan="12" style="text-align:center;padding:30px;">
|
|
Data tidak ditemukan
|
|
</td>
|
|
</tr>
|
|
|
|
@endforelse
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
@if(isset($skrining) && count($skrining) > 0)
|
|
|
|
<div class="pagination-wrapper-modern">
|
|
|
|
<div class="pagination-info">
|
|
|
|
Menampilkan
|
|
<b>{{ $skrining->firstItem() }}</b>
|
|
-
|
|
<b>{{ $skrining->lastItem() }}</b>
|
|
dari
|
|
<b>{{ $skrining->total() }}</b>
|
|
data
|
|
|
|
</div>
|
|
|
|
<div class="pagination-links-modern">
|
|
{{ $skrining->links() }}
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@endif
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<form
|
|
id="logout-form"
|
|
action="{{ route('logout') }}"
|
|
method="POST"
|
|
style="display:none;">
|
|
@csrf
|
|
</form>
|
|
|
|
<!-- MODAL -->
|
|
<div class="modal-overlay" id="modalSkrining">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h3>Detail Skrining</h3>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-icon"
|
|
onclick="closeSkrining()">
|
|
<i data-lucide="x" size="16"></i>
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="detail-layout">
|
|
|
|
<!-- KOLOM KIRI -->
|
|
<div class="detail-left">
|
|
|
|
<div class="patient-info">
|
|
|
|
<div class="patient-label">
|
|
Nama Pasien
|
|
</div>
|
|
|
|
<div class="patient-name" id="detail_nama"></div>
|
|
|
|
</div>
|
|
|
|
<div class="identity-grid">
|
|
|
|
<div class="identity-item">
|
|
<span>NIK</span>
|
|
<strong id="detail_nik">-</strong>
|
|
</div>
|
|
|
|
<div class="identity-item">
|
|
<span>Jenis Kelamin</span>
|
|
<strong id="detail_jk">-</strong>
|
|
</div>
|
|
|
|
<div class="identity-item">
|
|
<span>Tanggal Lahir</span>
|
|
<strong id="detail_tgl_lahir">-</strong>
|
|
</div>
|
|
|
|
<div class="identity-item">
|
|
<span>No. Telepon</span>
|
|
<strong id="detail_telp">-</strong>
|
|
</div>
|
|
|
|
<div class="identity-item-full" style="grid-column:1 / -1;">
|
|
<span>Alamat</span>
|
|
<strong id="detail_alamat">-</strong>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- KOLOM KANAN -->
|
|
<div class="detail-right">
|
|
|
|
<div id="result_card" class="result-card">
|
|
|
|
<div class="result-title">
|
|
Hasil Skrining
|
|
</div>
|
|
|
|
<div class="result-value" id="detail_status_text">
|
|
-
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="kuesioner-list">
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Batuk ≥ 2 minggu</p>
|
|
<p class="q-ans" id="ans_batuk"></p>
|
|
</div>
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Batuk lainnya</p>
|
|
<p class="q-ans" id="ans_batuk_lain"></p>
|
|
</div>
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Berat badan turun</p>
|
|
<p class="q-ans" id="ans_bb"></p>
|
|
</div>
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Demam hilang timbul</p>
|
|
<p class="q-ans" id="ans_demam"></p>
|
|
</div>
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Berkeringat malam</p>
|
|
<p class="q-ans" id="ans_keringat"></p>
|
|
</div>
|
|
|
|
<div class="q-item">
|
|
<p class="q-text">Pembesaran kelenjar</p>
|
|
<p class="q-ans" id="ans_kelenjar"></p>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer modal-footer-detail">
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-close-modal"
|
|
onclick="closeSkrining()">
|
|
Tutup
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- MODAL JADIKAN PASIEN -->
|
|
<div class="modal-overlay" id="modalJadikanPasien">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
<h3>Jadikan Pasien TB</h3>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn-icon info"
|
|
onclick="closeModalJadikanPasien()"
|
|
style="width:30px;height:30px;">
|
|
<i data-lucide="x" size="18"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<form
|
|
id="formJadikanPasien"
|
|
method="POST"
|
|
enctype="multipart/form-data">
|
|
|
|
<input type="hidden" id="jp_id_skrining" name="id_skrining">
|
|
<input type="hidden" id="jp_id_user" name="id_user">
|
|
|
|
<!-- DATA MEDIS -->
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
<label>Diagnosa</label>
|
|
<select name="diagnosa" required onchange="validateFormJadikanPasien()">
|
|
<option value="TBC Paru">TBC Paru</option>
|
|
<option value="TBC Ekstra Paru">TBC Ekstra Paru</option>
|
|
</select>
|
|
<small class="field-note">
|
|
Diagnosa wajib diisi
|
|
</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Jam Minum Obat</label>
|
|
<input type="time" name="jam_minum" required onchange="validateFormJadikanPasien()">
|
|
|
|
<small class="field-note">
|
|
Jam minum obat wajib diisi
|
|
</small>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-group">
|
|
<label>Tanggal Mulai Pengobatan</label>
|
|
<input type="date"
|
|
name="tgl_mulai"
|
|
id="tgl_mulai"
|
|
required
|
|
onchange="autoHitung168Hari()">
|
|
|
|
<small class="field-note">
|
|
Tanggal mulai wajib diisi
|
|
</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Tanggal Estimasi Selesai</label>
|
|
<input type="date" name="tgl_estimasi_selesai" id="tgl_estimasi_selesai" required readonly />
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- UPLOAD LAB -->
|
|
<div class="form-row">
|
|
|
|
<div class="form-group" style="width:100%;">
|
|
<label>Hasil Lab / Rontgen</label>
|
|
<input type="file"
|
|
name="file_lab[]"
|
|
multiple
|
|
required
|
|
accept=".pdf,.jpg,.jpeg,.png"
|
|
onchange="validateFormJadikanPasien()">
|
|
|
|
<small class="field-note">
|
|
File hasil lab wajib diupload
|
|
</small>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- RIWAYAT PENGOBATAN (tetap kamu boleh pakai kalau masih dipakai) -->
|
|
<div id="containerRiwayatPengobatan"></div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button"
|
|
class="btn btn-cancel"
|
|
onclick="closeModalJadikanPasien()">
|
|
Batal
|
|
</button>
|
|
|
|
<button
|
|
type="submit"
|
|
class="btn btn-submit"
|
|
id="btnSubmitPasien">
|
|
Simpan Sebagai Pasien
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
if (typeof lucide !== 'undefined') {
|
|
lucide.createIcons();
|
|
}
|
|
const today = new Date().toISOString().split('T')[0];
|
|
const tglMulai = document.getElementById('tgl_mulai');
|
|
|
|
if (tglMulai) {
|
|
tglMulai.setAttribute('max', today);
|
|
}
|
|
|
|
});
|
|
|
|
function toggleFilter() {
|
|
|
|
const content = document.getElementById('filterContent');
|
|
const icon = document.getElementById('filterIcon');
|
|
|
|
if (!content || !icon) return;
|
|
|
|
content.classList.toggle('active');
|
|
|
|
icon.style.transform =
|
|
content.classList.contains('active') ?
|
|
'rotate(180deg)' :
|
|
'rotate(0deg)';
|
|
}
|
|
|
|
function renderAns(id, val) {
|
|
|
|
const el = document.getElementById(id);
|
|
|
|
if (!el) return;
|
|
|
|
const isYes =
|
|
val == 1 ||
|
|
val === '1' ||
|
|
val === true ||
|
|
val === 'Ya';
|
|
|
|
el.innerText = isYes ? 'Ya' : 'Tidak';
|
|
|
|
el.className =
|
|
isYes ?
|
|
'q-ans text-red' :
|
|
'q-ans text-green';
|
|
}
|
|
|
|
function openSkrining(data, nama) {
|
|
|
|
document.getElementById('detail_nama').innerText =
|
|
nama || '-';
|
|
|
|
document.getElementById('detail_nik').innerText =
|
|
data.nik || '-';
|
|
|
|
document.getElementById('detail_jk').innerText =
|
|
data.jenis_kelamin || '-';
|
|
|
|
document.getElementById('detail_tgl_lahir').innerText =
|
|
data.tgl_lahir || '-';
|
|
|
|
document.getElementById('detail_telp').innerText =
|
|
data.no_telp || '-';
|
|
|
|
document.getElementById('detail_alamat').innerText =
|
|
data.alamat || '-';
|
|
const statusText =
|
|
document.getElementById('detail_status_text');
|
|
|
|
const resultCard =
|
|
document.getElementById('result_card');
|
|
statusText.innerText =
|
|
data.hasil_skrining || '-';
|
|
|
|
resultCard.classList.remove(
|
|
'terduga',
|
|
'tidak-terduga'
|
|
);
|
|
|
|
if (data.hasil_skrining === 'Terduga TBC') {
|
|
|
|
resultCard.classList.add('terduga');
|
|
|
|
} else {
|
|
|
|
resultCard.classList.add('tidak-terduga');
|
|
|
|
}
|
|
|
|
|
|
renderAns('ans_batuk', data.jwb_batuk);
|
|
renderAns('ans_batuk_lain', data.jwb_batuk_lain);
|
|
renderAns('ans_keringat', data.jwb_keringat_malam);
|
|
renderAns('ans_demam', data.jwb_demam);
|
|
renderAns('ans_kelenjar', data.jwb_pembesaran_kelenjar);
|
|
renderAns('ans_bb', data.jwb_berat_badan);
|
|
|
|
document.getElementById('modalSkrining').style.display =
|
|
'flex';
|
|
}
|
|
|
|
function closeSkrining() {
|
|
|
|
document.getElementById('modalSkrining').style.display =
|
|
'none';
|
|
}
|
|
|
|
function submitExport() {
|
|
|
|
const query = new URLSearchParams({
|
|
|
|
hasil_skrining: document.getElementById('filter_hasil').value,
|
|
|
|
fasyankes: document.getElementById('filter_fasyankes').value,
|
|
|
|
tgl_mulai: document.getElementById('filter_tgl_mulai').value,
|
|
|
|
tgl_selesai: document.getElementById('filter_tgl_selesai').value,
|
|
|
|
search: document.getElementById('searchInput').value
|
|
|
|
});
|
|
|
|
window.location.href =
|
|
"{{ route('skrining.export') }}?" +
|
|
query.toString();
|
|
}
|
|
|
|
const searchInput =
|
|
document.getElementById('searchInput');
|
|
|
|
if (searchInput) {
|
|
|
|
searchInput.addEventListener('keyup', function() {
|
|
|
|
const filter =
|
|
this.value.toLowerCase();
|
|
|
|
const rows =
|
|
document.querySelectorAll('#skriningTableBody tr');
|
|
|
|
rows.forEach(row => {
|
|
|
|
if (row.cells.length < 3) return;
|
|
|
|
const nama =
|
|
row.cells[1].textContent.toLowerCase();
|
|
|
|
const nik =
|
|
row.cells[2].textContent.toLowerCase();
|
|
|
|
row.style.display =
|
|
(nama.includes(filter) || nik.includes(filter)) ?
|
|
'' :
|
|
'none';
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function confirmDeleteSkrining(id, nama) {
|
|
|
|
Swal.fire({
|
|
|
|
icon: 'warning',
|
|
|
|
title: 'Hapus Skrining?',
|
|
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
Data skrining milik <b>${nama}</b>
|
|
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(`/skrining/hapus/${id}`, {
|
|
|
|
method: 'DELETE',
|
|
|
|
headers: {
|
|
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
|
'Accept': 'application/json'
|
|
}
|
|
|
|
})
|
|
|
|
.then(async response => {
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
data.message || 'Gagal menghapus'
|
|
);
|
|
}
|
|
|
|
return data;
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
Swal.fire({
|
|
|
|
icon: 'success',
|
|
|
|
title: 'Berhasil Dihapus',
|
|
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
Data skrining berhasil dihapus dari sistem.
|
|
</div>
|
|
`,
|
|
|
|
width: '340px',
|
|
|
|
timer: 1800,
|
|
|
|
showConfirmButton: false,
|
|
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal'
|
|
}
|
|
|
|
}).then(() => {
|
|
|
|
location.reload();
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
Swal.fire({
|
|
|
|
icon: 'error',
|
|
|
|
title: 'Gagal',
|
|
|
|
html: `
|
|
<div style="margin-top:5px;">
|
|
${error.message}
|
|
</div>
|
|
`,
|
|
|
|
width: '340px',
|
|
|
|
confirmButtonText: 'Tutup',
|
|
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function openSkriningFromButton(button) {
|
|
|
|
const data = JSON.parse(
|
|
button.dataset.item
|
|
.replace(/"/g, '"')
|
|
);
|
|
|
|
openSkrining(
|
|
data,
|
|
data.nama_lengkap
|
|
);
|
|
}
|
|
|
|
function openModalJadikanPasien(button) {
|
|
|
|
let data;
|
|
|
|
try {
|
|
|
|
const raw =
|
|
button.getAttribute('data-item');
|
|
|
|
data =
|
|
JSON.parse(raw);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'Data skrining gagal dibuka'
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
const userId =
|
|
data.id_user || data.id;
|
|
|
|
if (!userId) {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: 'ID User tidak ditemukan'
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
fetch(`/skrining/cek-pasien/${userId}`)
|
|
|
|
.then(response => {
|
|
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
'Gagal menghubungi server'
|
|
);
|
|
}
|
|
|
|
return response.json();
|
|
})
|
|
|
|
.then(res => {
|
|
|
|
if (res.exists) {
|
|
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Sudah Menjadi Pasien',
|
|
html: `
|
|
<div>
|
|
<b>${data.nama_lengkap}</b>
|
|
sudah terdaftar sebagai pasien.
|
|
</div>
|
|
`,
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal',
|
|
confirmButton: 'btn-confirm-swal'
|
|
}
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
document
|
|
.getElementById('formJadikanPasien')
|
|
.reset();
|
|
|
|
document.querySelectorAll(
|
|
'#formJadikanPasien .field-note'
|
|
).forEach(el => {
|
|
el.style.display = 'none';
|
|
});
|
|
|
|
document.querySelectorAll(
|
|
'#formJadikanPasien .field-error'
|
|
).forEach(el => {
|
|
el.classList.remove('field-error');
|
|
});
|
|
|
|
document
|
|
.getElementById('jp_id_skrining')
|
|
.value =
|
|
data.id_skrining || data.id || '';
|
|
|
|
document
|
|
.getElementById('jp_id_user')
|
|
.value =
|
|
userId;
|
|
|
|
document.getElementById(
|
|
'btnSubmitPasien'
|
|
).disabled = false;
|
|
|
|
document
|
|
.getElementById('modalJadikanPasien')
|
|
.style.display = 'flex';
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Error',
|
|
text: error.message
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function closeModalJadikanPasien() {
|
|
document.getElementById('modalJadikanPasien').style.display = 'none';
|
|
}
|
|
|
|
function generateRiwayatPengobatanSkrining(index) {
|
|
|
|
return `
|
|
|
|
<div class="pengobatan-item"
|
|
style="
|
|
border:1px solid #eee;
|
|
border-radius:16px;
|
|
padding:20px;
|
|
margin-top: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-pengobatan"
|
|
onclick="hapusRiwayatPengobatanSkrining(this)"
|
|
style="
|
|
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[${index}][diagnosa]"
|
|
required>
|
|
|
|
<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[${index}][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="{{ date('Y-m-d') }}"
|
|
onchange="hitungTanggalRiwayatPengobatan(this)">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Tanggal Selesai</label>
|
|
|
|
<input
|
|
type="date"
|
|
name="riwayat[${index}][tgl_selesai]"
|
|
readonly
|
|
required
|
|
style="background:#f3f4f6;">
|
|
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
|
|
<label>Status Pengobatan</label>
|
|
|
|
<select
|
|
name="riwayat[${index}][status_kesehatan]"
|
|
required>
|
|
|
|
<option value="Masih Proses" selected>
|
|
Masih Proses
|
|
</option>
|
|
|
|
<option value="Sembuh">
|
|
Sembuh
|
|
</option>
|
|
|
|
<option value="Gagal">
|
|
Gagal
|
|
</option>
|
|
|
|
<option value="Meninggal">
|
|
Meninggal
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function tambahRiwayatPengobatanSkrining() {
|
|
|
|
const container =
|
|
document.getElementById('containerRiwayatPengobatan');
|
|
|
|
const index =
|
|
container.querySelectorAll('.pengobatan-item').length;
|
|
|
|
container.insertAdjacentHTML(
|
|
'beforeend',
|
|
generateRiwayatPengobatanSkrining(index)
|
|
);
|
|
|
|
updateButtonHapusRiwayatPengobatan();
|
|
|
|
lucide.createIcons();
|
|
}
|
|
|
|
function hapusRiwayatPengobatanSkrining(btn) {
|
|
|
|
btn.closest('.pengobatan-item').remove();
|
|
|
|
resetNomorRiwayatPengobatan();
|
|
|
|
updateButtonHapusRiwayatPengobatan();
|
|
}
|
|
|
|
function updateButtonHapusRiwayatPengobatan() {
|
|
|
|
const items =
|
|
document.querySelectorAll(
|
|
'#containerRiwayatPengobatan .pengobatan-item'
|
|
);
|
|
|
|
items.forEach((item, index) => {
|
|
|
|
const btn =
|
|
item.querySelector('.btn-hapus-pengobatan');
|
|
|
|
if (!btn) return;
|
|
|
|
if (items.length > 1 && index === items.length - 1) {
|
|
|
|
btn.style.display = 'inline-block';
|
|
|
|
} else {
|
|
|
|
btn.style.display = 'none';
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
function resetNomorRiwayatPengobatan() {
|
|
|
|
const items =
|
|
document.querySelectorAll(
|
|
'#containerRiwayatPengobatan .pengobatan-item'
|
|
);
|
|
|
|
items.forEach((item, index) => {
|
|
|
|
item.querySelector('h4').innerText =
|
|
'Pengobatan Ke ' + (index + 1);
|
|
|
|
item.querySelectorAll('input, select')
|
|
.forEach(el => {
|
|
|
|
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('[status_kesehatan]')) {
|
|
el.name = `riwayat[${index}][status_kesehatan]`;
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
function autoHitung168Hari() {
|
|
|
|
const tglMulai = document.getElementById('tgl_mulai').value;
|
|
const tglSelesai = document.getElementById('tgl_estimasi_selesai');
|
|
|
|
if (!tglMulai) {
|
|
tglSelesai.value = '';
|
|
validateFormJadikanPasien();
|
|
return;
|
|
}
|
|
|
|
const date = new Date(tglMulai);
|
|
date.setDate(date.getDate() + 168);
|
|
|
|
const result = date.toISOString().split('T')[0];
|
|
|
|
tglSelesai.value = result;
|
|
|
|
validateFormJadikanPasien();
|
|
}
|
|
|
|
function validateFormJadikanPasien() {
|
|
|
|
let valid = true;
|
|
|
|
const fields = document.querySelectorAll(
|
|
'#formJadikanPasien input[required], #formJadikanPasien select[required]'
|
|
);
|
|
|
|
fields.forEach(field => {
|
|
|
|
let isEmpty = false;
|
|
|
|
if (field.type === 'file') {
|
|
|
|
isEmpty = field.files.length === 0;
|
|
|
|
} else {
|
|
|
|
isEmpty = !field.value;
|
|
}
|
|
|
|
const note =
|
|
field.parentElement.querySelector('.field-note');
|
|
|
|
if (isEmpty) {
|
|
|
|
valid = false;
|
|
|
|
field.classList.add('field-error');
|
|
|
|
if (note) {
|
|
note.style.display = 'block';
|
|
}
|
|
|
|
} else {
|
|
|
|
field.classList.remove('field-error');
|
|
|
|
if (note) {
|
|
note.style.display = 'none';
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
const btn = document.getElementById('btnSubmitPasien');
|
|
|
|
if (btn) {
|
|
btn.disabled = !valid;
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
document.getElementById('formJadikanPasien').addEventListener('submit', function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
if (!validateFormJadikanPasien()) {
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData(this);
|
|
|
|
formData.append(
|
|
'id_user',
|
|
document.getElementById('jp_id_user').value
|
|
);
|
|
|
|
formData.append(
|
|
'id_skrining',
|
|
document.getElementById('jp_id_skrining').value
|
|
);
|
|
|
|
fetch(`/skrining/jadikan-pasien/${document.getElementById('jp_id_skrining').value}`, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
'Accept': 'application/json'
|
|
}
|
|
})
|
|
.then(async response => {
|
|
const data = await response.json();
|
|
|
|
if (response.status === 409) {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Sudah Menjadi Pasien',
|
|
text: data.message
|
|
});
|
|
throw new Error('STOP'); // hentikan flow
|
|
}
|
|
|
|
if (!response.ok) {
|
|
throw new Error(data.message || 'Gagal');
|
|
}
|
|
|
|
return data;
|
|
})
|
|
.then(res => {
|
|
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Pasien Berhasil Terdaftar',
|
|
html: `
|
|
<div style="margin-top:8px; font-size:13px; color:#64748b;">
|
|
${res.message || 'Pengguna telah resmi menjadi pasien TB.'}
|
|
</div>
|
|
`,
|
|
width: '340px',
|
|
timer: 1800,
|
|
showConfirmButton: false,
|
|
customClass: {
|
|
popup: 'modern-popup',
|
|
title: 'title-swal'
|
|
},
|
|
didOpen: () => {
|
|
lucide.createIcons();
|
|
}
|
|
});
|
|
|
|
// RESET FORM TOTAL
|
|
document.getElementById('formJadikanPasien').reset();
|
|
document.getElementById('modalJadikanPasien').style.display = 'none';
|
|
|
|
// OPTIONAL: refresh table tanpa reload full page
|
|
setTimeout(() => {
|
|
location.reload();
|
|
}, 800);
|
|
|
|
})
|
|
.catch(err => {
|
|
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Gagal',
|
|
text: err.message
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
document.querySelectorAll(
|
|
'#formJadikanPasien input, #formJadikanPasien select'
|
|
).forEach(el => {
|
|
|
|
el.addEventListener('input', validateFormJadikanPasien);
|
|
el.addEventListener('change', validateFormJadikanPasien);
|
|
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html> |