MIF_E31231302_WEBSITE/resources/views/kelola-admin.blade.php

946 lines
28 KiB
PHP

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Kelola Admin - Sistem TBC</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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 {
width: 250px;
height: 100vh;
background: #c40000;
position: fixed;
padding-top: 30px;
overflow-y: auto;
}
.sidebar h2 {
color: white;
text-align: center;
margin-bottom: 40px;
}
.menu {
list-style: none;
}
.menu a {
text-decoration: none;
color: white;
display: flex;
align-items: center;
gap: 15px;
padding: 15px 25px;
transition: 0.3s;
}
.menu li.active a,
.menu li:hover a {
background: white;
color: #c40000;
border-radius: 30px 0 0 30px;
margin-left: 10px;
}
.main-content {
margin-left: 250px;
width: calc(100% - 250px);
padding: 40px;
}
.header-section {
margin-bottom: 25px;
}
.title-wrapper {
border-bottom: 1px solid #ddd;
padding-bottom: 15px;
margin-bottom: 20px;
}
.title {
font-size: 28px;
font-weight: 700;
color: #c40000;
margin-bottom: 10px;
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
.btn-add {
background: #c40000;
color: white;
border: none;
padding: 12px 20px;
border-radius: 12px;
cursor: pointer;
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
.search-box input {
width: 350px;
padding: 12px 15px;
border-radius: 12px;
border: 1px solid #ddd;
outline: none;
}
.table-container {
background: white;
border-radius: 20px;
padding: 20px;
overflow-x: auto;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
padding: 14px;
border-bottom: 1px solid #eee;
text-align: left;
font-size: 13px;
}
th {
background: #fafafa;
}
.badge {
padding: 8px 14px;
border-radius: 20px;
font-size: 12px;
font-weight: 700;
}
.badge-success {
background: #dcfce7;
color: #16a34a;
}
.badge-danger {
background: #fee2e2;
color: #dc2626;
}
.badge-role-admin {
background: #e0f2fe;
color: #0369a1;
}
.badge-role-super {
background: #fef9c3;
color: #a16207;
}
.action-group {
display: flex;
gap: 8px;
}
.btn-action {
width: 35px;
height: 35px;
border: none;
border-radius: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.btn-edit {
background: #eff6ff;
color: #2563eb;
}
.btn-delete {
background: #fee2e2;
color: #dc2626;
}
/* GANTI SEMUA CSS SWEETALERT LAMA MENJADI INI */
.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-popup.swal2-toast {
border-radius: 14px !important;
}
/* Modal Styles */
.modal {
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: 999;
}
.modal-content {
background: white;
width: 500px;
border-radius: 20px;
padding: 30px;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 16px;
position: relative;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-size: 13px;
font-weight: 600;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px;
border-radius: 12px;
border: 1px solid #ddd;
outline: none;
}
/* PERBAIKAN TAMPILAN PAGINATION SESUAI REQ */
.pagination-wrapper {
margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 5px;
}
.pagination-info {
font-size: 14px;
color: #64748b;
}
.pagination-links .pagination {
display: flex;
list-style: none;
gap: 5px;
}
.pagination-links .page-item .page-link {
padding: 8px 16px;
border: 1px solid #e2e8f0;
border-radius: 8px;
text-decoration: none;
color: #c40000;
background: white;
font-weight: 500;
}
.pagination-links .page-item.active .page-link {
background: #c40000;
color: white;
border-color: #c40000;
}
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-top: 20px;
}
.btn {
border: none;
padding: 12px 20px;
border-radius: 12px;
cursor: pointer;
font-weight: 600;
}
.btn-cancel {
background: #e2e8f0;
}
.btn-save {
background: #c40000;
color: white;
}
.note-default {
font-size: 12px;
color: #64748b;
margin-top: 5px;
}
</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>
<a href="{{ url('/skrining') }}">
<i data-lucide="stethoscope"></i>
Skrining
</a>
</li>
@if(session('role') == 'super_admin')
<li class="active">
<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-section">
<div class="title-wrapper">
<h1 class="title">Kelola Admin</h1>
</div>
<div class="top-bar">
<button class="btn-add" onclick="openTambahModal()">
<i data-lucide="plus"></i>
Tambah Admin
</button>
<form id="searchForm" method="GET" action="{{ url('/kelola-admin') }}">
<div class="search-box">
<input
type="text"
name="search"
id="searchInput"
placeholder="Cari Nama Admin atau Fasyankes..."
value="{{ request('search') }}"
oninput="doSearch()">
</div>
</form>
</div>
</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>No</th>
<th>ID</th>
<th>Nama Admin</th>
<th>Email</th>
<th>Role</th>
<th>Fasyankes</th>
<!-- <th>Status</th> -->
<th>Aksi</th>
</tr>
</thead>
<tbody>
@foreach($admin as $a)
<tr>
<td>{{ ($admin->currentPage() - 1) * $admin->perPage() + $loop->iteration }}</td>
<td>{{ $a->id_petugas }}</td>
<td>{{ $a->nama_petugas }}</td>
<td>{{ $a->email }}</td>
<td>
<span class="badge {{ $a->role == 'super_admin' ? 'badge-role-super' : 'badge-role-admin' }}">
{{ $a->role == 'super_admin' ? 'Super Admin' : 'Admin' }}
</span>
</td>
<td>{{ $a->role == 'admin' ? $a->nama_fasyankes : '-' }}</td>
<!-- <td>
<span class="badge {{ $a->status == 'aktif' ? 'badge-success' : 'badge-danger' }}">
{{ ucfirst($a->status) }}
</span>
</td> -->
<td>
<div class="action-group">
<button
class="btn-action btn-edit"
data-admin='@json($a)'
onclick="openEditModalFromButton(this)">
<i data-lucide="pencil"></i>
</button>
<button class="btn-action btn-delete" onclick="hapusAdmin('{{ $a->id_petugas }}')">
<i data-lucide="trash-2"></i>
</button>
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="pagination-wrapper">
<div class="pagination-info">
<span class="text-muted">
Menampilkan <b>{{ $admin->firstItem() }}</b> sampai <b>{{ $admin->lastItem() }}</b> dari <b>{{ $admin->total() }}</b> admin
</span>
</div>
<div class="pagination-links">
{{ $admin->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 Form -->
<div class="modal" id="modalAdmin">
<div class="modal-content">
<div class="modal-header">
<h3 id="modalTitle">Tambah Admin</h3>
<button onclick="closeModal()" style="background:none;border:none;cursor:pointer;">
<i data-lucide="x"></i>
</button>
</div>
<form id="formAdmin" method="POST">
@csrf
<input type="hidden" name="_method" id="hiddenMethod" value="POST">
<div class="form-group">
<label>Nama</label>
<input type="text" name="nama_petugas" id="nama_petugas" required>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" id="email" required>
</div>
<!-- <div class="form-group">
<label>Role</label>
<select name="role" id="role" required onchange="toggleFasyankes()">
<option value="">Pilih Role</option>
<option value="admin">Admin</option>
<option value="super_admin">Super Admin</option>
</select>
</div> -->
<div class="form-group">
<label>Fasyankes</label>
<select name="id_fasyankes" id="id_fasyankes" required>
<option value="">Pilih Fasyankes</option>
@foreach($fasyankes as $f)
<option value="{{ $f->id_fasyankes }}">
{{ $f->nama_fasyankes }}
</option>
@endforeach
</select>
</div>
<p class="note-default">
Password default akun otomatis: <b>12345678</b>
</p>
<!-- <div class="form-group" id="statusGroup" style="display:none;">
<label>Status Akun</label>
<select name="status" id="status">
<option value="aktif">Aktif</option>
<option value="nonaktif">Nonaktif</option>
</select>
</div> -->
<div class="modal-footer">
<button type="button" class="btn btn-cancel" onclick="closeModal()">Batal</button>
<button type="submit" class="btn btn-save">
Simpan
</button>
</div>
</form>
</div>
</div>
<script>
lucide.createIcons();
@if(session('error'))
Swal.fire({
icon: 'error',
title: 'Gagal Menambahkan Admin',
html: `
<div style="margin-top:8px; line-height:1.7;">
{{ session('error') }}
</div>
<div style="
margin-top:18px;
background:#fff1f2;
border:1px solid #fecdd3;
color:#be123c;
padding:14px;
border-radius:14px;
font-size:13px;
text-align:left;
">
<div style="
display:flex;
align-items:flex-start;
gap:10px;
">
<div style="
min-width:36px;
width:36px;
height:36px;
border-radius:12px;
background:#ffe4e6;
display:flex;
align-items:center;
justify-content:center;
">
<i data-lucide="shield-alert"
style="width:18px;height:18px;color:#e11d48;">
</i>
</div>
<div>
<div style="
font-weight:700;
margin-bottom:4px;
color:#9f1239;
">
Penyebab Gagal
</div>
<div style="font-size:12px;">
Setiap fasyankes hanya diperbolehkan memiliki
<b>1 akun admin aktif</b>.
Silakan pilih fasyankes lain atau edit admin sebelumnya.
</div>
</div>
</div>
</div>
`,
confirmButtonText: `
<div style="
display:flex;
align-items:center;
justify-content:center;
gap:8px;
">
<i data-lucide="circle-x"></i>
<span>Mengerti</span>
</div>
`,
customClass: {
popup: 'modern-popup',
title: 'title-swal',
confirmButton: 'btn-confirm-swal'
},
didOpen: () => {
lucide.createIcons();
}
});
@endif
@if(session('success'))
Swal.fire({
icon: 'success',
title: 'Berhasil',
html: `
<div style="margin-top:8px; line-height:1.7;">
{{ session('success') }}
</div>
<div style="
margin-top:18px;
background:#f0fdf4;
border:1px solid #bbf7d0;
color:#166534;
padding:14px;
border-radius:14px;
font-size:13px;
">
<div style="
display:flex;
align-items:center;
gap:10px;
">
<div style="
min-width:38px;
width:38px;
height:38px;
border-radius:12px;
background:#dcfce7;
display:flex;
align-items:center;
justify-content:center;
">
<i data-lucide="badge-check"
style="width:18px;height:18px;color:#16a34a;">
</i>
</div>
<div style="text-align:left;">
<div style="
font-weight:700;
margin-bottom:2px;
">
Admin Berhasil Ditambahkan
</div>
<div style="
font-size:12px;
color:#15803d;
">
Akun admin sudah aktif dan siap digunakan.
</div>
</div>
</div>
</div>
`,
confirmButtonText: `
<div style="
display:flex;
align-items:center;
justify-content:center;
gap:8px;
">
<i data-lucide="check"></i>
<span>Oke</span>
</div>
`,
customClass: {
popup: 'modern-popup',
title: 'title-swal',
confirmButton: 'btn-confirm-swal'
},
didOpen: () => {
lucide.createIcons();
}
});
@endif
let searchTimer;
function doSearch() {
clearTimeout(searchTimer);
searchTimer = setTimeout(() => {
document.getElementById('searchForm').submit();
}, 800);
}
// function toggleFasyankes() {
// const role = document.getElementById('role').value;
// const fasyankesGroup = document.getElementById('fasyankesGroup');
// const fasyankesSelect = document.getElementById('id_fasyankes');
// if (role === 'admin') {
// fasyankesGroup.style.display = 'block';
// fasyankesSelect.required = true;
// } else {
// fasyankesGroup.style.display = 'none';
// fasyankesSelect.required = false;
// fasyankesSelect.value = '';
// }
// }
function openTambahModal() {
document.getElementById('modalTitle').innerText = 'Tambah Admin';
document.getElementById('formAdmin').action =
'/kelola-admin/store';
document.getElementById('hiddenMethod').value = 'POST';
document.getElementById('nama_petugas').value = '';
document.getElementById('email').value = '';
document.getElementById('id_fasyankes').value = '';
// document.getElementById('statusGroup').style.display = 'none';
document.getElementById('modalAdmin').style.display = 'flex';
}
function openEditModal(data) {
document.getElementById('modalTitle').innerText = 'Edit Akun';
document.getElementById('formAdmin').action =
'/kelola-admin/update/' + data.id_petugas;
document.getElementById('hiddenMethod').value = 'PUT';
document.getElementById('nama_petugas').value =
data.nama_petugas;
document.getElementById('email').value =
data.email;
document.getElementById('id_fasyankes').value =
data.id_fasyankes ?? '';
document.getElementById('modalAdmin').style.display = 'flex';
}
function closeModal() {
document.getElementById('modalAdmin').style.display = 'none';
}
/* GANTI FUNCTION hapusAdmin() MENJADI INI */
function hapusAdmin(id) {
Swal.fire({
icon: 'warning',
title: 'Hapus Akun?',
html: `
<div style="margin-top:5px;">
Akun admin 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) {
Swal.fire({
title: 'Memproses...',
html: `
<div style="margin-top:5px;">
Sedang menghapus data akun admin.
</div>
`,
allowOutsideClick: false,
showConfirmButton: false,
customClass: {
popup: 'modern-popup',
title: 'title-swal'
},
didOpen: () => {
Swal.showLoading();
}
});
let form = document.createElement('form');
form.method = 'POST';
form.action = '/kelola-admin/delete/' + id;
form.innerHTML = `
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="DELETE">
`;
document.body.appendChild(form);
form.submit();
}
});
}
function confirmLogout() {
Swal.fire({
title: 'Logout?',
text: "Anda akan keluar dari sistem",
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#c40000',
confirmButtonText: 'Ya, Keluar'
}).then((result) => {
if (result.isConfirmed) {
document.getElementById('logout-form').submit();
}
});
}
function openEditModalFromButton(button) {
const data = JSON.parse(
button.getAttribute('data-admin')
);
openEditModal(data);
}
</script>
</body>
</html>