225 lines
9.0 KiB
PHP
225 lines
9.0 KiB
PHP
@extends('admin.layout')
|
|
|
|
@section('content')
|
|
<link rel="stylesheet" href="{{ asset('css/fitur-admin.css') }}">
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
|
|
<div class="dashboard-section">
|
|
<div class="master-page-header">
|
|
<div>
|
|
<h4 class="master-page-title">Manajemen Data Siswa</h4>
|
|
<p class="master-page-subtitle">Daftar siswa SMAN 4 Jember yang terdaftar di sistem.</p>
|
|
</div>
|
|
|
|
<a href="{{ route('admin.siswa.create') }}" class="btn-add-modern">
|
|
<i class="fas fa-plus"></i>
|
|
Tambah Siswa
|
|
</a>
|
|
</div>
|
|
|
|
<div class="table-container-modern shadow-sm">
|
|
<div class="table-toolbar">
|
|
<div class="search-wrapper-modern">
|
|
<i class="fas fa-search"></i>
|
|
<input type="text" id="searchInput" class="search-input-modern" placeholder="Cari nama siswa, NISN, atau kelas...">
|
|
</div>
|
|
|
|
<div class="per-page-wrapper">
|
|
<span>Tampilkan</span>
|
|
<select id="perPageSelect" class="per-page-select">
|
|
<option value="5">5 data</option>
|
|
<option value="7" selected>7 data</option>
|
|
<option value="10">10 data</option>
|
|
<option value="20">20 data</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="tableContent">
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Konfigurasi API Mandiri
|
|
const API_SISWA_URL = "https://ta.myhost.id/E31230935/api/admin/siswa";
|
|
const LOGIN_URL = "https://ta.myhost.id/E31230935/login";
|
|
|
|
function getToken() {
|
|
return localStorage.getItem('access_token');
|
|
}
|
|
|
|
async function parseJsonResponse(response) {
|
|
if (response.status === 401 || response.status === 403) {
|
|
Swal.fire('Sesi Berakhir', 'Silakan login ulang.', 'warning')
|
|
.then(() => window.location.href = LOGIN_URL);
|
|
return { success: false, message: 'Unauthorized' };
|
|
}
|
|
return await response.json();
|
|
}
|
|
|
|
let currentPage = 1;
|
|
let currentSearch = '';
|
|
let perPage = 7;
|
|
let searchTimer;
|
|
|
|
async function fetchSiswa(page = 1) {
|
|
currentPage = page;
|
|
const tableContent = document.getElementById('tableContent');
|
|
tableContent.innerHTML = '<div class="text-center py-5 text-muted"><span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span> Memuat data...</div>';
|
|
|
|
try {
|
|
const token = getToken();
|
|
const response = await fetch(`${API_SISWA_URL}?page=${page}&per_page=${perPage}&search=${encodeURIComponent(currentSearch)}`, {
|
|
headers: {
|
|
'Authorization': 'Bearer ' + token,
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
const data = await parseJsonResponse(response);
|
|
|
|
if (response.ok && data.success !== false) {
|
|
renderTable(data.data.data, data.data.current_page, data.data.per_page);
|
|
renderPagination(data.data);
|
|
} else {
|
|
tableContent.innerHTML = `<div class="text-center py-5 text-danger"><i class="fas fa-exclamation-triangle fa-3x mb-3"></i><p>Gagal memuat data: ${data.message || 'Error server'}</p></div>`;
|
|
}
|
|
} catch (error) {
|
|
tableContent.innerHTML = `<div class="text-center py-5 text-danger"><i class="fas fa-wifi fa-3x mb-3"></i><p>Gagal menghubungi server. Periksa koneksi internet Anda.</p></div>`;
|
|
}
|
|
}
|
|
|
|
function renderTable(siswaData, currentPage, perPage) {
|
|
const tableContent = document.getElementById('tableContent');
|
|
|
|
if (siswaData.length === 0) {
|
|
tableContent.innerHTML = '<div class="text-center py-5 text-muted"><i class="fas fa-folder-open fa-3x mb-3"></i><p>Tidak ada data siswa yang ditemukan.</p></div>';
|
|
return;
|
|
}
|
|
|
|
let html = `
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle table-modern">
|
|
<thead>
|
|
<tr>
|
|
<th width="5%" class="text-center">No</th>
|
|
<th width="25%">Nama Lengkap</th>
|
|
<th width="20%">NISN</th>
|
|
<th width="15%" class="text-center">Kelas</th>
|
|
<th width="20%">Username</th>
|
|
<th width="15%" class="text-center">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
`;
|
|
|
|
siswaData.forEach((siswa, index) => {
|
|
const no = (currentPage - 1) * perPage + (index + 1);
|
|
const editUrl = `{{ url('/admin/siswa') }}/${siswa.id}/edit`;
|
|
const username = siswa.user ? siswa.user.username : '<span class="text-danger small">Tidak ada akun</span>';
|
|
|
|
html += `
|
|
<tr>
|
|
<td class="text-center">${no}</td>
|
|
<td class="fw-bold">${siswa.nama_lengkap || '-'}</td>
|
|
<td><span class="badge bg-light text-dark border">${siswa.nisn || '-'}</span></td>
|
|
<td class="text-center"><span class="badge" style="background-color: #2D7A47;">${siswa.kelas || '-'}</span></td>
|
|
<td>${username}</td>
|
|
<td class="text-center">
|
|
<div class="d-flex justify-content-center gap-2">
|
|
<a href="${editUrl}" class="btn btn-sm btn-outline-primary shadow-sm" title="Edit Data">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
<button onclick="deleteSiswa(${siswa.id})" class="btn btn-sm btn-outline-danger shadow-sm" title="Hapus Data">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
|
|
html += `
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="paginationWrapper" class="d-flex justify-content-between align-items-center p-3 border-top bg-light mt-3 rounded-bottom"></div>
|
|
`;
|
|
|
|
tableContent.innerHTML = html;
|
|
}
|
|
|
|
function renderPagination(meta) {
|
|
const paginationWrapper = document.getElementById('paginationWrapper');
|
|
if (!paginationWrapper) return;
|
|
|
|
let html = `<div class="text-muted small fw-bold">Menampilkan ${meta.from || 0} - ${meta.to || 0} dari ${meta.total || 0} Data</div>`;
|
|
html += `<div class="d-flex gap-2">`;
|
|
|
|
if (meta.current_page > 1) {
|
|
html += `<button onclick="fetchSiswa(${meta.current_page - 1})" class="btn btn-sm btn-light border fw-bold text-muted shadow-sm"><i class="fas fa-chevron-left me-1"></i> Sebelumnya</button>`;
|
|
}
|
|
|
|
if (meta.current_page < meta.last_page) {
|
|
html += `<button onclick="fetchSiswa(${meta.current_page + 1})" class="btn btn-sm btn-light border fw-bold text-muted shadow-sm">Selanjutnya <i class="fas fa-chevron-right ms-1"></i></button>`;
|
|
}
|
|
|
|
html += `</div>`;
|
|
paginationWrapper.innerHTML = html;
|
|
}
|
|
|
|
async function deleteSiswa(id) {
|
|
const confirmResult = await Swal.fire({
|
|
title: 'Hapus data?',
|
|
text: "Data yang dihapus tidak dapat dikembalikan!",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#3085d6',
|
|
confirmButtonText: 'Ya, Hapus!',
|
|
cancelButtonText: 'Batal'
|
|
});
|
|
|
|
if (!confirmResult.isConfirmed) return;
|
|
|
|
const token = getToken();
|
|
try {
|
|
const response = await fetch(`${API_SISWA_URL}/${id}`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Authorization': 'Bearer ' + token,
|
|
'Accept': 'application/json'
|
|
}
|
|
});
|
|
const resultDelete = await parseJsonResponse(response);
|
|
|
|
if (response.ok && resultDelete.success !== false) {
|
|
Swal.fire('Terhapus!', resultDelete.message || 'Data berhasil dihapus.', 'success');
|
|
fetchSiswa(currentPage);
|
|
} else {
|
|
Swal.fire('Gagal!', resultDelete.message || 'Gagal menghapus data.', 'error');
|
|
}
|
|
} catch (error) {
|
|
Swal.fire('Error!', 'Gagal menghubungi server.', 'error');
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
fetchSiswa(1);
|
|
|
|
document.getElementById('searchInput').addEventListener('input', function () {
|
|
clearTimeout(searchTimer);
|
|
searchTimer = setTimeout(() => {
|
|
currentSearch = this.value.trim();
|
|
fetchSiswa(1);
|
|
}, 500);
|
|
});
|
|
|
|
document.getElementById('perPageSelect').addEventListener('change', function () {
|
|
perPage = parseInt(this.value);
|
|
fetchSiswa(1);
|
|
});
|
|
});
|
|
</script>
|
|
@endsection |