feat: apply revisions for UI/UX and role-based features

This commit is contained in:
zhadaarsita 2026-02-23 02:07:01 +07:00
parent 692ee5009b
commit 2ccee78660
23 changed files with 1339 additions and 947 deletions

View File

@ -12,29 +12,47 @@ class AdminPeminjamanController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$peminjamanAktif = DummyDataService::getAdminPeminjamanAktif(); $peminjamanAktif = DummyDataService::getAdminPeminjamanAktif();
$allUsers = collect(DummyDataService::getAllSiswa());
// LOGIC DENDA & WA LINK (Update Request Client) // LOGIC DENDA & WA LINK (Update Request Client)
$peminjamanAktif = $peminjamanAktif->map(function ($item) { $peminjamanAktif = $peminjamanAktif->map(function ($item) use ($allUsers) {
$userData = $allUsers->firstWhere('id', $item['user_id']);
$role = $userData ? strtolower($userData['role']) : 'siswa';
$item['role'] = $role;
// Hitung Denda Flat 1000/hari // Hitung Denda Flat 1000/hari
$tenggat = Carbon::parse($item['tenggat_kembali']); $tenggat = Carbon::parse($item['tenggat_kembali']);
$now = Carbon::now(); $now = Carbon::now();
$item['hari_terlambat'] = 0; $item['hari_terlambat'] = 0;
$item['total_denda'] = 0; $item['total_denda'] = 0;
$item['denda_per_hari'] = 1000;
if ($now->greaterThan($tenggat)) { if ($now->greaterThan($tenggat)) {
$hariTelat = $tenggat->diffInDays($now); $hariTelat = $tenggat->diffInDays($now);
$item['hari_terlambat'] = $hariTelat; $item['hari_terlambat'] = $hariTelat;
$item['total_denda'] = $hariTelat * 1000;
$item['denda_per_hari'] = 1000; if ($role === 'guru') {
$item['total_denda'] = 0;
$item['denda_per_hari'] = 0;
} else {
$item['total_denda'] = $hariTelat * 1000;
}
} }
// Generate WA Link // Generate WA Link
$hp = $item['nomor_hp']; $hp = $item['nomor_hp'];
if (substr($hp, 0, 1) == '0') { if (substr($hp, 0, 1) == '0') {
$hp = '62' . substr($hp, 1); $hp = '62' . substr($hp, 1);
} }
$pesan = "Halo kak {$item['peminjam']}, buku anda sudah terlambat {$item['hari_terlambat']} hari dengan denda Rp " . number_format($item['total_denda'], 0, ',', '.') . ". Mohon segera dikembalikan ya."; // Pesan WA dibedakan antara Guru dan Siswa
if ($role === 'guru') {
$pesan = "Halo Bapak/Ibu {$item['peminjam']}, buku yang dipinjam sudah melewati tenggat waktu {$item['hari_terlambat']} hari. Mohon berkenan untuk segera dikembalikan ke perpustakaan ya.";
} else {
$pesan = "Halo kak {$item['peminjam']}, buku anda sudah terlambat {$item['hari_terlambat']} hari dengan denda Rp " . number_format($item['total_denda'], 0, ',', '.') . ". Mohon segera dikembalikan ya.";
}
$item['wa_link'] = "https://wa.me/{$hp}?text=" . urlencode($pesan); $item['wa_link'] = "https://wa.me/{$hp}?text=" . urlencode($pesan);
return $item; return $item;
@ -43,7 +61,7 @@ public function index(Request $request)
$daftarPeminjam = $peminjamanAktif->pluck('peminjam')->unique(); $daftarPeminjam = $peminjamanAktif->pluck('peminjam')->unique();
return view('admin.peminjaman.index', [ return view('admin.peminjaman.index', [
'pageTitle' => 'Manajemen Peminjaman & Denda', 'pageTitle' => 'Manajemen Peminjaman',
'peminjamanAktif' => $peminjamanAktif, 'peminjamanAktif' => $peminjamanAktif,
'daftarPeminjam' => $daftarPeminjam, 'daftarPeminjam' => $daftarPeminjam,
]); ]);
@ -61,9 +79,12 @@ public function create()
// Hitung berapa buku yang sedang dipinjam // Hitung berapa buku yang sedang dipinjam
$jumlahPinjam = $peminjamanAktif->where('peminjam', $user['nama_lengkap'])->count(); $jumlahPinjam = $peminjamanAktif->where('peminjam', $user['nama_lengkap'])->count();
// Cek Status
$user['jumlah_pinjam'] = $jumlahPinjam; $user['jumlah_pinjam'] = $jumlahPinjam;
$user['kena_limit'] = $jumlahPinjam >= 2; if (strtolower($user['role']) === 'siswa') {
$user['kena_limit'] = $jumlahPinjam >= 2;
} else {
$user['kena_limit'] = false;
}
// Cek apakah user di-banned (Nonaktif Manual) // Cek apakah user di-banned (Nonaktif Manual)
$user['is_banned'] = $user['is_banned'] ?? false; $user['is_banned'] = $user['is_banned'] ?? false;
@ -77,6 +98,8 @@ public function create()
$user['status_text'] = ""; $user['status_text'] = "";
} }
$user['jabatan'] = $user['jabatan'] ?? 'Guru Mata Pelajaran';
return $user; return $user;
}) })
->groupBy('role'); ->groupBy('role');
@ -108,17 +131,13 @@ public function dendaIndex()
// LOGIC AUTO-BAN // LOGIC AUTO-BAN
$allSiswa = $allSiswaRaw->map(function ($siswa) use ($allData, $now) { $allSiswa = $allSiswaRaw->map(function ($siswa) use ($allData, $now) {
// Cek siswa punya pinjaman yang telat
$pinjamanUser = $allData->firstWhere('user_id', $siswa['id']); $pinjamanUser = $allData->firstWhere('user_id', $siswa['id']);
$isTelat = false; $isTelat = false;
if ($pinjamanUser) { if ($pinjamanUser) {
$isTelat = $pinjamanUser['tenggat_kembali']->startOfDay()->lt($now->startOfDay()); $isTelat = $pinjamanUser['tenggat_kembali']->startOfDay()->lt($now->startOfDay());
} }
// Jika Role SISWA dan TELAT -> Wajib AUTO BAN (Override true)
// ika Role GURU -> Ikut status asli database (Manual Ban)
if ($siswa['role'] === 'siswa' && $isTelat) { if ($siswa['role'] === 'siswa' && $isTelat) {
$siswa['is_banned'] = true; $siswa['is_banned'] = true;
} }
@ -129,8 +148,7 @@ public function dendaIndex()
$siswaTelat = $allData->filter(function ($item) use ($now, $allSiswa) { $siswaTelat = $allData->filter(function ($item) use ($now, $allSiswa) {
$userData = $allSiswa->firstWhere('id', $item['user_id']); $userData = $allSiswa->firstWhere('id', $item['user_id']);
if (!$userData) if (!$userData) return false;
return false;
$isTelat = $item['tenggat_kembali']->startOfDay()->lt($now->startOfDay()); $isTelat = $item['tenggat_kembali']->startOfDay()->lt($now->startOfDay());
$isBanned = $userData['is_banned']; $isBanned = $userData['is_banned'];
@ -139,34 +157,35 @@ public function dendaIndex()
return ($isTelat || $isBanned) && $isTargetRole; return ($isTelat || $isBanned) && $isTargetRole;
})->map(function ($item) use ($now, $allSiswa) { })->map(function ($item) use ($now, $allSiswa) {
// Hitungan Denda
$tenggat = $item['tenggat_kembali']->startOfDay(); $tenggat = $item['tenggat_kembali']->startOfDay();
$hariTelat = ($tenggat->lt($now->startOfDay())) ? $tenggat->diffInDays($now->startOfDay()) : 0;
// Jika belum telat (tapi banned/manual), hari telat 0 $dataSiswa = $allSiswa->firstWhere('id', $item['user_id']);
$hariTelat = ($tenggat->lt($now->startOfDay())) $role = $dataSiswa ? strtolower($dataSiswa['role']) : 'siswa';
? $tenggat->diffInDays($now->startOfDay()) $item['role'] = $role;
: 0;
$totalDenda = $hariTelat * $item['denda_per_hari']; if ($role === 'guru') {
$item['total_denda'] = 0;
} else {
$item['total_denda'] = $hariTelat * $item['denda_per_hari'];
}
$item['hari_terlambat'] = $hariTelat; $item['hari_terlambat'] = $hariTelat;
$item['total_denda'] = $totalDenda;
// Ambil status is_banned TERBARU dari $allSiswa
$dataSiswa = $allSiswa->firstWhere('id', $item['user_id']);
$item['is_banned'] = $dataSiswa['is_banned'] ?? false; $item['is_banned'] = $dataSiswa['is_banned'] ?? false;
$item['kelas'] = $dataSiswa['kelas'] ?? 'Guru'; $item['kelas'] = $dataSiswa['kelas'] ?? 'Guru';
// Link WA // Link WA
$hp = $item['nomor_hp']; $hp = $item['nomor_hp'];
if (substr($hp, 0, 1) == '0') if (substr($hp, 0, 1) == '0') $hp = '62' . substr($hp, 1);
$hp = '62' . substr($hp, 1);
if ($hariTelat > 0) { if ($hariTelat > 0 && $role !== 'guru') {
$pesan = "Halo {$item['peminjam']}, anda terlambat pengembalian buku. Total Denda: Rp " . number_format($totalDenda, 0, ',', '.'); $pesan = "Halo {$item['peminjam']}, anda terlambat pengembalian buku. Total Denda: Rp " . number_format($item['total_denda'], 0, ',', '.');
} elseif ($hariTelat > 0 && $role === 'guru') {
$pesan = "Halo Bapak/Ibu {$item['peminjam']}, mohon berkenan untuk mengembalikan buku yang telah melewati tenggat waktu.";
} else { } else {
$pesan = "Halo {$item['peminjam']}, akun anda sedang dinonaktifkan sementara. Mohon hubungi petugas."; $pesan = "Halo {$item['peminjam']}, akun anda sedang dinonaktifkan sementara. Mohon hubungi petugas.";
} }
$item['wa_link'] = "https://wa.me/{$hp}?text=" . urlencode($pesan); $item['wa_link'] = "https://wa.me/{$hp}?text=" . urlencode($pesan);
return $item; return $item;

View File

@ -12,7 +12,14 @@ class UserController extends Controller
{ {
public function index() public function index()
{ {
$users = User::orderBy('created_at', 'desc')->paginate(10); $query = User::orderBy('created_at', 'desc');
if (request()->has('role') && request('role') != '') {
$query->where('role', request('role'));
}
$users = $query->paginate(10)->appends(request()->query());
$whitelists = MasterInduk::orderBy('created_at', 'desc')->get(); $whitelists = MasterInduk::orderBy('created_at', 'desc')->get();
return view('admin.pengguna.index', [ return view('admin.pengguna.index', [

View File

@ -4,16 +4,24 @@
use App\Services\DummyDataService; use App\Services\DummyDataService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; // Tambahkan ini use Illuminate\Support\Facades\Auth;
class RiwayatController extends Controller class RiwayatController extends Controller
{ {
public function offlineIndex() public function offlineIndex()
{ {
$user = \Illuminate\Support\Facades\Auth::user(); $user = Auth::user();
if (!$user) $user = (object) ['id' => 1]; if (!$user) $user = (object) ['id' => 1];
$riwayatOffline = DummyDataService::getRiwayatOffline($user); $dataOffline = DummyDataService::getRiwayatOffline($user);
$riwayatOffline = collect($dataOffline)
->sortBy([
['status', 'asc'],
['tanggal_pinjam', 'desc']
])
->values()
->all();
return view('riwayat.offline', [ return view('riwayat.offline', [
'pageTitle' => 'Riwayat Peminjaman Offline', 'pageTitle' => 'Riwayat Peminjaman Offline',
@ -23,7 +31,15 @@ public function offlineIndex()
public function onlineIndex() public function onlineIndex()
{ {
$riwayatOnline = DummyDataService::getRiwayatOnline(); $dataOnline = DummyDataService::getRiwayatOnline();
$riwayatOnline = collect($dataOnline)
->sortBy([
['status', 'asc'],
['tanggal_baca', 'desc']
])
->values()
->all();
return view('riwayat.online', [ return view('riwayat.online', [
'pageTitle' => 'Riwayat Baca Online', 'pageTitle' => 'Riwayat Baca Online',

View File

@ -13,43 +13,42 @@
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<div class="card-body"> <div class="card-body">
<form action="#" method="POST"> {{-- TAMBAHKAN ID PADA FORM --}}
{{-- Form ini tidak akan berfungsi karena tidak ada backend --}} <form action="#" method="POST" id="formTambahBuku">
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<div class="mb-3"> <div class="mb-3">
<label for="judul" class="form-label">Judul Buku</label> <label for="judul" class="form-label">Judul Buku</label>
<input type="text" class="form-control" id="judul" <input type="text" class="form-control" id="judul" placeholder="Masukkan judul buku" required>
placeholder="Masukkan judul buku">
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="penulis" class="form-label">Penulis</label> <label for="penulis" class="form-label">Penulis</label>
<input type="text" class="form-control" id="penulis" <input type="text" class="form-control" id="penulis" placeholder="Masukkan nama penulis" required>
placeholder="Masukkan nama penulis">
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-4 mb-3"> <div class="col-md-3 mb-3">
<label for="kategori" class="form-label">Kategori</label> <label for="kategori" class="form-label">Kategori</label>
<input type="text" class="form-control" id="kategori" <input type="text" class="form-control" id="kategori" placeholder="Contoh: Fiksi" required>
placeholder="Contoh: Fiksi, Sains">
</div> </div>
<div class="col-md-4 mb-3"> <div class="col-md-3 mb-3">
<label for="tahun" class="form-label">Tahun Terbit</label> <label for="tahun" class="form-label">Tahun Terbit</label>
<input type="number" class="form-control" id="tahun" <input type="number" class="form-control" id="tahun" min="1000" max="2099" oninput="this.value = Math.abs(this.value)" placeholder="Contoh: 2024" required>
placeholder="Contoh: 2024">
</div> </div>
<div class="col-md-4 mb-3"> <div class="col-md-3 mb-3">
<label for="kode_buku" class="form-label">Kode Buku</label> <label for="kode_buku" class="form-label">Kode Buku</label>
<input type="number" class="form-control" id="kode_buku" <input type="text" class="form-control" id="kode_buku" placeholder="Contoh: 330" required>
placeholder="Contoh: 330"> </div>
<div class="col-md-3 mb-3">
<label for="stok_buku" class="form-label">Stok Buku</label>
<input type="number" class="form-control" id="stok_buku" min="0" oninput="this.value = Math.abs(this.value)" placeholder="Contoh: 15" required>
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Tipe Akses</label> <label class="form-label">Tipe Akses</label>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="tipe_offline"> <input class="form-check-input" type="checkbox" id="tipe_offline" checked>
<label class="form-check-label" for="tipe_offline">Peminjaman <label class="form-check-label" for="tipe_offline">Peminjaman Offline</label>
Offline</label>
</div> </div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="tipe_online"> <input class="form-check-input" type="checkbox" id="tipe_online">
@ -77,5 +76,29 @@
</div> </div>
</div> </div>
</div> </div>
</div>z </div>
</x-app-layout>
@push('scripts')
<script>
document.getElementById('formTambahBuku').addEventListener('submit', function(e) {
e.preventDefault();
modernSwal.fire({
title: 'Menyimpan...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Buku baru berhasil ditambahkan.'
});
setTimeout(() => {
window.location.href = "{{ route('admin.buku.index') }}";
}, 1500);
});
});
</script>
@endpush
</x-app-layout>

View File

@ -13,60 +13,55 @@
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<div class="card-body"> <div class="card-body">
<form action="#" method="POST"> {{-- TAMBAHKAN ID PADA FORM --}}
{{-- Form ini tidak akan berfungsi karena tidak ada backend --}} <form action="#" method="POST" id="formEditBuku">
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<div class="mb-3"> <div class="mb-3">
<label for="judul" class="form-label">Judul Buku</label> <label for="judul" class="form-label">Judul Buku</label>
<input type="text" class="form-control" id="judul" <input type="text" class="form-control" id="judul" value="{{ $buku['judul'] }}" required>
value="{{ $buku['judul'] }}">
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="penulis" class="form-label">Penulis</label> <label for="penulis" class="form-label">Penulis</label>
<input type="text" class="form-control" id="penulis" <input type="text" class="form-control" id="penulis" value="{{ $buku['penulis'] }}" required>
value="{{ $buku['penulis'] }}">
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="kategori" class="form-label">Kategori</label> <label for="kategori" class="form-label">Kategori</label>
<input type="text" class="form-control" id="kategori" <input type="text" class="form-control" id="kategori" value="{{ $buku['kategori'] }}" required>
value="{{ $buku['kategori'] }}">
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="tahun" class="form-label">Tahun Terbit</label> <label for="tahun" class="form-label">Tahun Terbit</label>
<input type="number" class="form-control" id="tahun" <input type="number" class="form-control" id="tahun" value="{{ $buku['tahun'] }}" min="1000" max="2099" oninput="this.value = Math.abs(this.value)" required>
value="{{ $buku['tahun'] }}">
</div> </div>
</div> </div>
@php @php
$tipe_akses = is_array($buku['tipe_akses']) $tipe_akses = is_array($buku['tipe_akses']) ? $buku['tipe_akses'] : [$buku['tipe_akses']];
? $buku['tipe_akses']
: [$buku['tipe_akses']];
$isOffline = in_array('offline', $tipe_akses); $isOffline = in_array('offline', $tipe_akses);
@endphp @endphp
{{-- Field Kode Buku - Hanya untuk Buku Offline --}}
@if($isOffline) @if($isOffline)
<div class="mb-3"> <div class="row">
<label for="kode_buku" class="form-label">Kode Buku</label> <div class="col-md-6 mb-3">
<input type="text" class="form-control" id="kode_buku" <label for="kode_buku" class="form-label">Kode Buku</label>
value="{{ $buku['kode_buku'] ?? '' }}" placeholder="Masukkan kode buku"> <input type="text" class="form-control" id="kode_buku" value="{{ $buku['kode_buku'] ?? '' }}" placeholder="Masukkan kode buku" required>
</div>
<div class="col-md-6 mb-3">
<label for="stok_buku" class="form-label">Stok Buku</label>
<input type="number" class="form-control" id="stok_buku" value="{{ $buku['stok'] ?? 0 }}" min="0" oninput="this.value = Math.abs(this.value)" required>
</div>
</div> </div>
@endif @endif
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Tipe Akses (Tidak dapat diubah)</label> <label class="form-label">Tipe Akses (Tidak dapat diubah)</label>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="tipe_offline" <input class="form-check-input" type="checkbox" id="tipe_offline" @if (in_array('offline', $tipe_akses)) checked @endif disabled>
@if (in_array('offline', $tipe_akses)) checked @endif disabled> <label class="form-check-label" for="tipe_offline">Peminjaman Offline</label>
<label class="form-check-label" for="tipe_offline">Peminjaman
Offline</label>
</div> </div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="tipe_online" <input class="form-check-input" type="checkbox" id="tipe_online" @if (in_array('online', $tipe_akses)) checked @endif disabled>
@if (in_array('online', $tipe_akses)) checked @endif disabled>
<label class="form-check-label" for="tipe_online">Baca Online</label> <label class="form-check-label" for="tipe_online">Baca Online</label>
</div> </div>
</div> </div>
@ -76,8 +71,7 @@
<div class="mb-3"> <div class="mb-3">
<label for="cover" class="form-label">Cover Buku</label> <label for="cover" class="form-label">Cover Buku</label>
<input type="file" class="form-control" id="cover"> <input type="file" class="form-control" id="cover">
<img src="{{ asset($buku['cover']) }}" alt="Cover saat ini" <img src="{{ asset($buku['cover']) }}" alt="Cover saat ini" class="img-thumbnail mt-2" width="150">
class="img-thumbnail mt-2" width="150">
</div> </div>
</div> </div>
</div> </div>
@ -91,4 +85,28 @@ class="img-thumbnail mt-2" width="150">
</div> </div>
</div> </div>
</div> </div>
@push('scripts')
<script>
document.getElementById('formEditBuku').addEventListener('submit', function(e) {
e.preventDefault();
modernSwal.fire({
title: 'Menyimpan Perubahan...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Data buku berhasil diperbarui.'
});
setTimeout(() => {
window.location.href = "{{ route('admin.buku.index') }}";
}, 1500);
});
});
</script>
@endpush
</x-app-layout> </x-app-layout>

View File

@ -11,13 +11,14 @@
<div class="card-body"> <div class="card-body">
<ul class="nav nav-tabs" id="bukuTab" role="tablist"> <ul class="nav nav-tabs" id="bukuTab" role="tablist">
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link active" id="offline-tab" data-bs-toggle="tab" <button class="nav-link active" id="offline-tab" data-bs-toggle="tab" data-bs-target="#offline-tab-pane" type="button" role="tab">Peminjaman Offline (<span id="countOffline">{{ $bukuOffline->count() }}</span>)</button>
data-bs-target="#offline-tab-pane" type="button" role="tab">Peminjaman Offline
({{ $bukuOffline->count() }})</button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="online-tab" data-bs-toggle="tab" data-bs-target="#online-tab-pane" <button class="nav-link" id="online-tab" data-bs-toggle="tab" data-bs-target="#online-tab-pane" type="button" role="tab">Baca Online (<span id="countOnline">{{ $bukuOnline->count() }}</span>)</button>
type="button" role="tab">Baca Online ({{ $bukuOnline->count() }})</button> </li>
{{-- TAB BARU KHUSUS ARSIP --}}
<li class="nav-item" role="presentation">
<button class="nav-link text-warning" id="arsip-tab" data-bs-toggle="tab" data-bs-target="#arsip-tab-pane" type="button" role="tab"><i class="bi bi-archive-fill me-1"></i>Diarsipkan (<span id="countArsip">0</span>)</button>
</li> </li>
</ul> </ul>
@ -25,7 +26,7 @@
{{-- TAB UNTUK BUKU OFFLINE --}} {{-- TAB UNTUK BUKU OFFLINE --}}
<div class="tab-pane fade show active" id="offline-tab-pane" role="tabpanel"> <div class="tab-pane fade show active" id="offline-tab-pane" role="tabpanel">
<div class="table-responsive mt-3"> <div class="table-responsive mt-3">
<table class="table table-hover"> <table class="table table-hover align-middle" id="tableOffline">
<thead> <thead>
<tr> <tr>
<th>No</th> <th>No</th>
@ -33,45 +34,46 @@
<th>Judul</th> <th>Judul</th>
<th>Kode Buku</th> <th>Kode Buku</th>
<th>Penulis</th> <th>Penulis</th>
<th>Stok</th>
<th>Status</th> <th>Status</th>
<th>Aksi</th> <th class="text-center">Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse($bukuOffline as $buku) @forelse($bukuOffline as $buku)
<tr> <tr data-tipe="offline">
<td>{{ $loop->iteration }}</td> <td class="row-number">{{ $loop->iteration }}</td>
<td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}" <td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}" width="40" class="rounded shadow-sm"></td>
width="50" class="rounded"></td> <td class="fw-bold">{{ $buku['judul'] }}</td>
<td>{{ $buku['judul'] }}</td>
<td>{{ $buku['kode_buku'] }}</td> <td>{{ $buku['kode_buku'] }}</td>
<td>{{ $buku['penulis'] }}</td> <td>{{ $buku['penulis'] }}</td>
<td><span class="badge bg-secondary">{{ $buku['stok'] ?? 0 }}</span></td>
<td> <td>
@if ($buku['status'] == 'Tersedia') @if ($buku['status'] == 'Tersedia')
<span <span class="badge bg-success-subtle text-success-emphasis">Tersedia</span>
class="badge bg-success-subtle text-success-emphasis">Tersedia</span>
@else @else
<span <span class="badge bg-warning-subtle text-warning-emphasis">Dipinjam</span>
class="badge bg-warning-subtle text-warning-emphasis">Dipinjam</span>
@endif @endif
</td> </td>
<td> <td>
<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" <div class="d-flex justify-content-center gap-2 aksi-buttons">
data-bs-target="#detailBukuModal" data-id="{{ $buku['id'] }}" <button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal"
data-cover="{{ asset($buku['cover']) }}" data-bs-target="#detailBukuModal" data-id="{{ $buku['id'] }}"
data-judul="{{ $buku['judul'] }}" data-cover="{{ asset($buku['cover']) }}" data-judul="{{ $buku['judul'] }}"
data-kode_buku="{{ $buku['kode_buku'] }}" data-kode_buku="{{ $buku['kode_buku'] }}" data-penulis="{{ $buku['penulis'] }}"
data-penulis="{{ $buku['penulis'] }}" data-kategori="{{ $buku['kategori'] }}" data-tahun="{{ $buku['tahun'] }}"
data-kategori="{{ $buku['kategori'] }}" data-status="{{ $buku['status'] }}">
data-tahun="{{ $buku['tahun'] }}" data-status="{{ $buku['status'] }}"> <i class="bi bi-eye-fill"></i> Detail
<i class="bi bi-eye-fill"></i> Detail </button>
</button> <button class="btn btn-sm btn-outline-warning btn-arsipkan"
data-judul="{{ $buku['judul'] }}" title="Arsipkan Buku">
<i class="bi bi-archive-fill"></i> Arsip
</button>
</div>
</td> </td>
</tr> </tr>
@empty @empty
<tr> <tr class="empty-row"><td colspan="8" class="text-center py-4">Tidak ada data buku offline.</td></tr>
<td colspan="6" class="text-center py-4">Tidak ada data buku offline.</td>
</tr>
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
@ -81,7 +83,7 @@ class="badge bg-warning-subtle text-warning-emphasis">Dipinjam</span>
{{-- TAB UNTUK BUKU ONLINE --}} {{-- TAB UNTUK BUKU ONLINE --}}
<div class="tab-pane fade" id="online-tab-pane" role="tabpanel"> <div class="tab-pane fade" id="online-tab-pane" role="tabpanel">
<div class="table-responsive mt-3"> <div class="table-responsive mt-3">
<table class="table table-hover"> <table class="table table-hover align-middle" id="tableOnline">
<thead> <thead>
<tr> <tr>
<th>No</th> <th>No</th>
@ -89,45 +91,67 @@ class="badge bg-warning-subtle text-warning-emphasis">Dipinjam</span>
<th>Judul</th> <th>Judul</th>
<th>Penulis</th> <th>Penulis</th>
<th>File PDF</th> <th>File PDF</th>
<th>Aksi</th> <th class="text-center">Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse($bukuOnline as $buku) @forelse($bukuOnline as $buku)
<tr> <tr data-tipe="online">
<td>{{ $loop->iteration }}</td> <td class="row-number">{{ $loop->iteration }}</td>
<td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}" <td><img src="{{ asset($buku['cover']) }}" alt="{{ $buku['judul'] }}" width="40" class="rounded shadow-sm"></td>
width="50" class="rounded"></td> <td class="fw-bold">{{ $buku['judul'] }}</td>
<td>{{ $buku['judul'] }}</td>
<td>{{ $buku['penulis'] }}</td> <td>{{ $buku['penulis'] }}</td>
<td><span <td><span class="badge bg-info-subtle text-info-emphasis">{{ $buku['file_pdf'] ?? 'N/A' }}</span></td>
class="badge bg-info-subtle text-info-emphasis">{{ $buku['file_pdf'] ?? 'N/A' }}</span>
</td>
<td> <td>
<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" <div class="d-flex justify-content-center gap-2 aksi-buttons">
data-bs-target="#detailBukuModal" data-id="{{ $buku['id'] }}" <button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal"
data-cover="{{ asset($buku['cover']) }}" data-bs-target="#detailBukuModal" data-id="{{ $buku['id'] }}"
data-judul="{{ $buku['judul'] }}" data-cover="{{ asset($buku['cover']) }}" data-judul="{{ $buku['judul'] }}"
data-penulis="{{ $buku['penulis'] }}" data-penulis="{{ $buku['penulis'] }}" data-kategori="{{ $buku['kategori'] }}"
data-kategori="{{ $buku['kategori'] }}" data-tahun="{{ $buku['tahun'] }}" data-status="Dapat Dibaca Online">
data-tahun="{{ $buku['tahun'] }}" data-status="Dapat Dibaca Online"> <i class="bi bi-eye-fill"></i> Detail
<i class="bi bi-eye-fill"></i> Detail </button>
</button> <button class="btn btn-sm btn-outline-warning btn-arsipkan"
data-judul="{{ $buku['judul'] }}" title="Arsipkan Buku">
<i class="bi bi-archive-fill"></i> Arsip
</button>
</div>
</td> </td>
</tr> </tr>
@empty @empty
<tr> <tr class="empty-row"><td colspan="6" class="text-center py-4">Tidak ada data buku online.</td></tr>
<td colspan="6" class="text-center py-4">Tidak ada data buku online.</td>
</tr>
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{{-- TAB UNTUK ARSIP --}}
<div class="tab-pane fade" id="arsip-tab-pane" role="tabpanel">
<div class="table-responsive mt-3">
<table class="table table-hover align-middle" id="tableArsip">
<thead>
<tr>
<th>No</th>
<th>Cover</th>
<th>Judul</th>
<th>Penulis</th>
<th>Tipe</th>
<th class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
<tr class="empty-row-arsip"><td colspan="6" class="text-center py-4 text-muted"><i class="bi bi-inbox fs-4 d-block mb-2"></i>Belum ada buku yang diarsipkan.</td></tr>
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
{{-- MODAL DETAIL BUKU --}}
<div class="modal fade" id="detailBukuModal" tabindex="-1"> <div class="modal fade" id="detailBukuModal" tabindex="-1">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
@ -137,37 +161,24 @@ class="badge bg-info-subtle text-info-emphasis">{{ $buku['file_pdf'] ?? 'N/A' }}
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4 text-center mb-4 mb-md-0">
<img src="" id="modalCover" class="img-fluid rounded shadow-sm" alt="Cover Buku"> <img src="" id="modalCover" class="img-fluid rounded shadow mx-auto d-block" style="max-height: 250px; object-fit: cover;" alt="Cover Buku">
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<h3 id="modalJudulContent" class="fw-bold"></h3> <h3 id="modalJudulContent" class="fw-bold text-dark"></h3>
<p class="text-muted" id="modalPenulis"></p> <p class="text-muted mb-4" id="modalPenulis"></p>
<table class="table table-sm table-borderless"> <table class="table table-sm table-borderless">
<tr> <tr><th width="120px" class="text-black">Kategori</th><td id="modalKategori" class="fw-semibold"></td></tr>
<th width="100px">Kategori</th> <tr id="rowKodeBuku"><th class="text-black">Kode Buku</th><td id="modalKode_buku" class="fw-semibold"></td></tr>
<td id="modalKategori"></td> <tr><th class="text-black">Tahun Terbit</th><td id="modalTahun" class="fw-semibold"></td></tr>
</tr> <tr><th class="text-black">Status</th><td><span id="modalStatus" class="badge"></span></td></tr>
<tr id="rowKodeBuku">
<th>Kode Buku</th>
<td id="modalKode_buku"></td>
</tr>
<tr>
<th>Tahun</th>
<td id="modalTahun"></td>
</tr>
<tr>
<th>Status</th>
<td><span id="modalStatus" class="badge"></span></td>
</tr>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer bg-light">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
<a href="#" id="modalEditButton" class="btn btn-primary"><i <a href="#" id="modalEditButton" class="btn btn-primary"><i class="bi bi-pencil-fill me-2"></i>Edit Buku</a>
class="bi bi-pencil-fill me-2"></i>Edit Buku</a>
</div> </div>
</div> </div>
</div> </div>
@ -176,6 +187,7 @@ class="bi bi-pencil-fill me-2"></i>Edit Buku</a>
@push('scripts') @push('scripts')
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
// LOGIC UNTUK MODAL DETAIL
const detailBukuModal = document.getElementById('detailBukuModal'); const detailBukuModal = document.getElementById('detailBukuModal');
if (detailBukuModal) { if (detailBukuModal) {
detailBukuModal.addEventListener('show.bs.modal', event => { detailBukuModal.addEventListener('show.bs.modal', event => {
@ -212,7 +224,6 @@ class="bi bi-pencil-fill me-2"></i>Edit Buku</a>
modalStatus.textContent = status; modalStatus.textContent = status;
modalEditButton.href = editUrl; modalEditButton.href = editUrl;
// Tampilkan/sembunyikan kode buku berdasarkan ada tidaknya data
if (kode_buku && kode_buku !== 'null' && kode_buku !== '') { if (kode_buku && kode_buku !== 'null' && kode_buku !== '') {
rowKodeBuku.style.display = ''; rowKodeBuku.style.display = '';
modalKode_buku.textContent = `: ${kode_buku}`; modalKode_buku.textContent = `: ${kode_buku}`;
@ -227,7 +238,90 @@ class="bi bi-pencil-fill me-2"></i>Edit Buku</a>
} }
}); });
} }
function updateTableNumbers() {
let countOffline = 0;
$('#tableOffline tbody tr').not('.empty-row').each(function(index) {
$(this).find('.row-number').text(index + 1);
countOffline++;
});
$('#countOffline').text(countOffline);
let countOnline = 0;
$('#tableOnline tbody tr').not('.empty-row').each(function(index) {
$(this).find('.row-number').text(index + 1);
countOnline++;
});
$('#countOnline').text(countOnline);
let countArsip = 0;
$('#tableArsip tbody tr').not('.empty-row-arsip').each(function(index) {
$(this).find('.row-number').text(index + 1);
countArsip++;
});
$('#countArsip').text(countArsip);
if(countArsip === 0) {
$('.empty-row-arsip').show();
} else {
$('.empty-row-arsip').hide();
}
}
// LOGIC UNTUK TOMBOL ARSIPKAN
$(document).on('click', '.btn-arsipkan', function() {
const judul = $(this).data('judul');
const row = $(this).closest('tr');
const coverHtml = row.find('td:eq(1)').html();
const tipe = row.data('tipe');
const penulis = tipe === 'offline' ? row.find('td:eq(4)').text() : row.find('td:eq(3)').text();
modernSwal.fire({
title: 'Arsipkan Buku?',
text: `Apakah Anda yakin ingin mengarsipkan buku "${judul}"?`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Arsipkan!',
cancelButtonText: 'Batal',
confirmButtonColor: '#ffc107',
cancelButtonColor: '#6c757d'
}).then((result) => {
if (result.isConfirmed) {
modernSwal.fire({
title: 'Memproses...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: `Buku "${judul}" telah dipindahkan ke Arsip.`
});
let badgeTipe = tipe === 'offline' ? '<span class="badge bg-secondary">Offline</span>' : '<span class="badge bg-info">Online</span>';
let newRow = `
<tr>
<td class="row-number"></td>
<td>${coverHtml}</td>
<td class="fw-bold text-muted">${judul}</td>
<td class="text-muted">${penulis}</td>
<td>${badgeTipe}</td>
<td class="text-center">
<span class="badge bg-warning"><i class="bi bi-archive-fill me-1"></i>Diarsipkan</span>
</td>
</tr>
`;
row.fadeOut('slow', function() {
$(this).remove();
$('#tableArsip tbody').append(newRow);
updateTableNumbers();
});
});
}
});
});
}); });
</script> </script>
@endpush @endpush
</x-app-layout> </x-app-layout>

View File

@ -4,7 +4,7 @@
<div class="d-flex justify-content-between align-items-center mb-4"> <div class="d-flex justify-content-between align-items-center mb-4">
<div> <div>
<h3 class="my-0 fw-bold">Manajemen Denda & Sanksi</h3> <h3 class="my-0 fw-bold">Manajemen Denda & Sanksi</h3>
<p class="text-muted mb-0">Pantau siswa terlambat dan berikan sanksi jika diperlukan.</p> <p class="text-muted mb-0">Pantau pengguna terlambat dan berikan sanksi jika diperlukan.</p>
</div> </div>
</div> </div>
@ -17,7 +17,7 @@
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<select id="filterKelas" class="form-select form-select-sm"> <select id="filterKelas" class="form-select form-select-sm">
<option value="">Semua Kelas</option> <option value="">Semua Kelas/Golongan</option>
@foreach ($listKelas as $kelas) @foreach ($listKelas as $kelas)
<option value="{{ $kelas }}">{{ $kelas }}</option> <option value="{{ $kelas }}">{{ $kelas }}</option>
@endforeach @endforeach
@ -46,7 +46,7 @@
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<th class="text-center" width="5%">NO</th> <th class="text-center" width="5%">NO</th>
<th width="25%">SISWA & KELAS</th> <th width="25%">NAMA</th>
<th width="25%">BUKU TERLAMBAT</th> <th width="25%">BUKU TERLAMBAT</th>
<th width="15%">STATUS</th> <th width="15%">STATUS</th>
<th width="15%">DENDA</th> <th width="15%">DENDA</th>
@ -59,10 +59,10 @@
<td class="text-center">{{ $loop->iteration }}</td> <td class="text-center">{{ $loop->iteration }}</td>
<td> <td>
<div class="fw-bold text-dark">{{ $item['peminjam'] }}</div> <div class="fw-bold text-dark">{{ $item['peminjam'] }}</div>
<span <span class="badge bg-light text-secondary border mt-1 mb-1">{{ $item['kelas'] }}</span>
class="badge bg-light text-secondary border mt-1 mb-1">{{ $item['kelas'] }}</span> <div class="small text-muted">
<div class="small text-muted"><i <i class="bi bi-telephone me-1"></i>{{ $item['nomor_hp'] }}
class="bi bi-telephone me-1"></i>{{ $item['nomor_hp'] }}</div> </div>
</td> </td>
<td> <td>
<ul class="mb-0 ps-3 small text-muted"> <ul class="mb-0 ps-3 small text-muted">
@ -71,42 +71,54 @@ class="bi bi-telephone me-1"></i>{{ $item['nomor_hp'] }}</div>
@endforeach @endforeach
</ul> </ul>
</td> </td>
{{-- KOLOM STATUS --}}
<td data-order="{{ $item['tenggat_kembali']->timestamp }}"> <td data-order="{{ $item['tenggat_kembali']->timestamp }}">
<span @if(isset($item['role']) && strtolower($item['role']) === 'guru')
class="badge bg-danger-subtle text-danger border border-danger-subtle rounded-pill px-3"> <div class="fw-bold text-muted">-</div>
Telat {{ $item['hari_terlambat'] }} Hari @else
</span> <span class="badge bg-danger-subtle text-danger border border-danger-subtle rounded-pill px-3">
<div class="small text-muted mt-1"> Telat {{ $item['hari_terlambat'] }} Hari
Tenggat: {{ $item['tenggat_kembali']->format('d/m/Y') }} </span>
</div> <div class="small text-muted mt-1">
Tenggat: {{ $item['tenggat_kembali']->format('d/m/Y') }}
</div>
@endif
</td> </td>
<td data-order="{{ $item['total_denda'] }}"> {{-- KOLOM DENDA --}}
<div class="fw-bold text-danger">Rp <td data-order="{{ isset($item['role']) && strtolower($item['role']) === 'guru' ? 0 : $item['total_denda'] }}">
{{ number_format($item['total_denda'], 0, ',', '.') }}</div> @if(isset($item['role']) && strtolower($item['role']) === 'guru')
<small class="text-muted" style="font-size: 0.75rem;">Rp 1.000/hari</small> <div class="fw-bold text-muted">-</div>
@else
<div class="fw-bold text-danger">Rp {{ number_format($item['total_denda'], 0, ',', '.') }}</div>
<small class="text-muted" style="font-size: 0.75rem;">Rp 1.000/hari</small>
@endif
</td> </td>
{{-- KOLOM AKSI --}}
<td> <td>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
{{-- Tombol WA --}} {{-- Tombol WA (Muncul untuk semua) --}}
<a href="{{ $item['wa_link'] }}" target="_blank" <a href="{{ $item['wa_link'] }}" target="_blank"
class="btn btn-sm btn-success text-white" title="Tagih via WhatsApp"> class="btn btn-sm btn-success text-white" title="Tagih via WhatsApp">
<i class="bi bi-whatsapp"></i> <i class="bi bi-whatsapp"></i>
</a> </a>
{{-- LOGIC TOMBOL AKTIFKAN / SANKSI --}} @if(!isset($item['role']) || strtolower($item['role']) !== 'guru')
@if ($item['is_banned']) @if ($item['is_banned'])
{{-- Jika sudah dibekukan (Otomatis/Manual), muncul tombol AKTIFKAN --}} {{-- Jika sudah dibekukan (Otomatis/Manual), muncul tombol AKTIFKAN --}}
<button class="btn btn-sm btn-outline-success btn-aktifkan" <button class="btn btn-sm btn-outline-success btn-aktifkan"
data-nama="{{ $item['peminjam'] }}" title="Aktifkan Kembali Akun"> data-nama="{{ $item['peminjam'] }}" title="Aktifkan Kembali Akun">
<i class="bi bi-shield-check"></i> Aktifkan <i class="bi bi-shield-check"></i> Aktifkan
</button> </button>
@else @else
{{-- Jika belum dibekukan, muncul tombol SANKSI (Manual) --}} {{-- Jika belum dibekukan, muncul tombol SANKSI (Manual) --}}
<button class="btn btn-sm btn-outline-danger btn-sanksi" <button class="btn btn-sm btn-outline-danger btn-sanksi"
data-nama="{{ $item['peminjam'] }}" title="Berikan Sanksi"> data-nama="{{ $item['peminjam'] }}" title="Berikan Sanksi">
<i class="bi bi-slash-circle"></i> Sanksi <i class="bi bi-slash-circle"></i> Sanksi
</button> </button>
@endif
@endif @endif
</div> </div>
</td> </td>
@ -116,7 +128,7 @@ class="btn btn-sm btn-success text-white" title="Tagih via WhatsApp">
<td colspan="6" class="text-center py-5"> <td colspan="6" class="text-center py-5">
<div class="text-muted opacity-50"> <div class="text-muted opacity-50">
<i class="bi bi-emoji-smile fs-1 mb-2 d-block"></i> <i class="bi bi-emoji-smile fs-1 mb-2 d-block"></i>
<p class="mb-0">Tidak ada siswa yang terlambat hari ini.</p> <p class="mb-0">Tidak ada buku terlambat hari ini.</p>
</div> </div>
</td> </td>
</tr> </tr>
@ -143,7 +155,7 @@ class="btn btn-sm btn-success text-white" title="Tagih via WhatsApp">
language: { language: {
search: "_INPUT_", search: "_INPUT_",
searchPlaceholder: "Cari nama siswa..." searchPlaceholder: "Cari nama peminjam..."
}, },
dom: 'rtip' dom: 'rtip'
}); });
@ -187,7 +199,7 @@ function(settings, data, dataIndex) {
$(document).on('click', '.btn-sanksi', function() { $(document).on('click', '.btn-sanksi', function() {
const nama = $(this).data('nama'); const nama = $(this).data('nama');
modernSwal.fire({ modernSwal.fire({
title: 'Nonaktifkan Guru?', title: 'Nonaktifkan Akun?',
text: `Apakah Anda yakin ingin memberikan sanksi pembekuan akun kepada ${nama}?`, text: `Apakah Anda yakin ingin memberikan sanksi pembekuan akun kepada ${nama}?`,
icon: 'warning', icon: 'warning',
showCancelButton: true, showCancelButton: true,
@ -245,4 +257,4 @@ function(settings, data, dataIndex) {
}); });
</script> </script>
@endpush @endpush
</x-app-layout> </x-app-layout>

View File

@ -18,15 +18,17 @@
<h5 class="fw-bold mb-3">Data Peminjaman</h5> <h5 class="fw-bold mb-3">Data Peminjaman</h5>
<div class="mb-3"> <div class="mb-3">
<label for="peminjam_id" class="form-label">Pilih Peminjam (Siswa/Guru)</label> <label for="peminjam_id" class="form-label">Pilih Peminjam (Siswa/Guru)</label>
<select class="form-control" id="peminjam_id" name="peminjam_id" placeholder="Cari nama atau email...">
<select class="form-control" id="peminjam_id" name="peminjam_id"
placeholder="Cari nama atau email...">
<option value="">Pilih...</option> <option value="">Pilih...</option>
@foreach ($groupedUsers as $role => $users) @foreach ($groupedUsers as $role => $users)
<optgroup label="{{ ucfirst($role) }}"> <optgroup label="{{ ucfirst($role) }}">
@foreach ($users as $user) @foreach ($users as $user)
{{-- Logic Disable User --}}
<option value="{{ $user['id'] }}" <option value="{{ $user['id'] }}"
data-role="{{ strtolower($role) }}"
data-identitas="{{ $user['nip'] ?? $user['nisn'] ?? '-' }}"
data-kontak="{{ $user['no_hp'] ?? '-' }}"
data-info="{{ strtolower($role) == 'guru' ? ($user['jabatan'] ?? 'Guru') : ($user['kelas'] ?? 'Siswa') }}"
{{ $user['disabled'] ? 'disabled' : '' }}> {{ $user['disabled'] ? 'disabled' : '' }}>
{{ $user['nama_lengkap'] }} {{ $user['status_text'] }} {{ $user['nama_lengkap'] }} {{ $user['status_text'] }}
</option> </option>
@ -36,16 +38,24 @@
</select> </select>
</div> </div>
<div id="detailPeminjamCard" class="alert alert-secondary d-none mb-3">
<h6 class="fw-bold mb-2 border-bottom pb-1"><i class="bi bi-person-badge me-2"></i>Detail Identitas</h6>
<div class="row small">
<div class="col-6 mb-1"><span class="text-muted">NIP/NISN:</span> <strong id="lblIdentitas">-</strong></div>
<div class="col-6 mb-1"><span class="text-muted">No. HP:</span> <strong id="lblKontak">-</strong></div>
<div class="col-6"><span class="text-muted">Jabatan/Kelas:</span> <strong id="lblInfo">-</strong></div>
<div class="col-6"><span class="text-muted">Role:</span> <strong id="lblRole" class="text-uppercase">-</strong></div>
</div>
</div>
<div class="row g-3"> <div class="row g-3">
<div class="col-md-6"> <div class="col-md-6">
<label for="tanggal_pinjam" class="form-label">Tanggal Pinjam</label> <label for="tanggal_pinjam" class="form-label">Tanggal Pinjam</label>
<input type="text" class="form-control" id="tanggal_pinjam" name="tanggal_pinjam" <input type="text" class="form-control" id="tanggal_pinjam" name="tanggal_pinjam" placeholder="Pilih tanggal pinjam">
placeholder="Pilih tanggal pinjam">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label for="tanggal_kembali" class="form-label">Tenggat Kembali</label> <label for="tanggal_kembali" class="form-label">Tenggat Kembali</label>
<input type="text" class="form-control" id="tanggal_kembali" name="tanggal_kembali" <input type="text" class="form-control" id="tanggal_kembali" name="tanggal_kembali" placeholder="Pilih tenggat kembali">
placeholder="Pilih tenggat kembali">
</div> </div>
</div> </div>
@ -84,8 +94,7 @@
<div class="mb-3"> <div class="mb-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-text bg-white"><i class="bi bi-search"></i></span> <span class="input-group-text bg-white"><i class="bi bi-search"></i></span>
<input type="text" class="form-control border-start-0" id="searchBuku" <input type="text" class="form-control border-start-0" id="searchBuku" placeholder="Cari judul atau penulis...">
placeholder="Cari judul atau penulis...">
</div> </div>
</div> </div>
@ -98,19 +107,15 @@
data-book-kategori="{{ $buku['kategori'] }}"> data-book-kategori="{{ $buku['kategori'] }}">
<div class="d-flex align-items-center book-item-list" <div class="d-flex align-items-center book-item-list"
onclick="toggleBookSelection(this, {{ $buku['id'] }})" onclick="toggleBookSelection(this, {{ $buku['id'] }})" style="cursor: pointer;">
style="cursor: pointer;"> <img src="{{ asset($buku['cover']) }}" alt="Cover" class="rounded me-3" style="width: 50px; height: 70px; object-fit: cover;">
<img src="{{ asset($buku['cover']) }}" alt="Cover" class="rounded me-3"
style="width: 50px; height: 70px; object-fit: cover;">
<div class="flex-grow-1"> <div class="flex-grow-1">
<h6 class="fw-bold mb-1 line-clamp-2">{{ $buku['judul'] }}</h6> <h6 class="fw-bold mb-1 line-clamp-2">{{ $buku['judul'] }}</h6>
<p class="text-muted small mb-1">{{ $buku['penulis'] }}</p> <p class="text-muted small mb-1">{{ $buku['penulis'] }}</p>
<span class="badge bg-info-soft">{{ $buku['kategori'] }}</span> <span class="badge bg-info-soft">{{ $buku['kategori'] }}</span>
</div> </div>
<div class="form-check ms-3"> <div class="form-check ms-3">
<input class="form-check-input book-checkbox" type="checkbox" <input class="form-check-input book-checkbox" type="checkbox" value="{{ $buku['id'] }}" id="book-check-{{ $buku['id'] }}" style="pointer-events: none;">
value="{{ $buku['id'] }}" id="book-check-{{ $buku['id'] }}"
style="pointer-events: none;">
</div> </div>
</div> </div>
</div> </div>
@ -122,53 +127,47 @@
</div> </div>
</form> </form>
@push('scripts') @push('scripts')
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const tomSelect = new TomSelect("#peminjam_id", { const tomSelect = new TomSelect("#peminjam_id", {
create: false, create: false,
sortField: { sortField: { field: "text", direction: "asc" },
field: "text", onChange: function(value) {
direction: "asc" // Munculkan Kartu Detail Peminjam saat Dropdown Berubah
} const selectedOption = this.options[value];
}); const detailCard = document.getElementById('detailPeminjamCard');
const tglPinjam = flatpickr("#tanggal_pinjam", { if(selectedOption && value !== "") {
dateFormat: "Y-m-d", document.getElementById('lblRole').textContent = selectedOption.dataset.role;
altInput: true, document.getElementById('lblIdentitas').textContent = selectedOption.dataset.identitas;
altFormat: "d/m/Y", document.getElementById('lblKontak').textContent = selectedOption.dataset.kontak;
defaultDate: "today", document.getElementById('lblInfo').textContent = selectedOption.dataset.info;
locale: "id", detailCard.classList.remove('d-none');
onChange: function(selectedDates, dateStr) { } else {
if (selectedDates.length > 0) { detailCard.classList.add('d-none');
tglKembali.set("minDate", new Date(selectedDates[0]).fp_incr(1));
} }
} }
}); });
const tglKembali = flatpickr("#tanggal_kembali", { const tglPinjam = flatpickr("#tanggal_pinjam", {
dateFormat: "Y-m-d", dateFormat: "Y-m-d", altInput: true, altFormat: "d/m/Y", defaultDate: "today", locale: "id",
altInput: true, onChange: function(selectedDates, dateStr) {
altFormat: "d/m/Y", if (selectedDates.length > 0) tglKembali.set("minDate", new Date(selectedDates[0]).fp_incr(1));
defaultDate: new Date().fp_incr(7), }
locale: "id",
minDate: new Date().fp_incr(1)
}); });
const tglKembali = flatpickr("#tanggal_kembali", {
dateFormat: "Y-m-d", altInput: true, altFormat: "d/m/Y", defaultDate: new Date().fp_incr(7), locale: "id", minDate: new Date().fp_incr(1)
});
// Logika Pemilihan Buku const MAX_BOOKS_SISWA = 2;
const MAX_BOOKS = 2;
let selectedBookIds = new Set(); let selectedBookIds = new Set();
const allBooks = new Map(); const allBooks = new Map();
document.querySelectorAll('.book-option').forEach(el => { document.querySelectorAll('.book-option').forEach(el => {
const id = el.dataset.bookId; const id = el.dataset.bookId;
allBooks.set(id, { allBooks.set(id, { id: id, title: el.querySelector('h6').textContent, author: el.querySelector('p').textContent, cover: el.dataset.bookCover });
id: id,
title: el.querySelector('h6').textContent,
author: el.querySelector('p').textContent,
cover: el.dataset.bookCover
});
}); });
const daftarBukuPinjamEl = document.getElementById('daftarBukuPinjam'); const daftarBukuPinjamEl = document.getElementById('daftarBukuPinjam');
@ -176,21 +175,14 @@
const counterBukuEl = document.getElementById('counterBuku'); const counterBukuEl = document.getElementById('counterBuku');
const emptyStateBukuEl = document.getElementById('emptyStateBuku'); const emptyStateBukuEl = document.getElementById('emptyStateBuku');
// Fungsi render
function renderSelectedBooks() { function renderSelectedBooks() {
daftarBukuPinjamEl.querySelectorAll('.selected-book-item').forEach(el => el.remove()); daftarBukuPinjamEl.querySelectorAll('.selected-book-item').forEach(el => el.remove());
hiddenInputsEl.innerHTML = ''; hiddenInputsEl.innerHTML = '';
emptyStateBukuEl.style.display = selectedBookIds.size === 0 ? 'block' : 'none';
if (selectedBookIds.size === 0) {
emptyStateBukuEl.style.display = 'block';
} else {
emptyStateBukuEl.style.display = 'none';
}
selectedBookIds.forEach(id => { selectedBookIds.forEach(id => {
const book = allBooks.get(String(id)); const book = allBooks.get(String(id));
if (!book) return; if (!book) return;
const itemHtml = ` const itemHtml = `
<div class="selected-book-item book-item d-flex align-items-start p-3 mb-2 rounded" data-selected-id="${id}"> <div class="selected-book-item book-item d-flex align-items-start p-3 mb-2 rounded" data-selected-id="${id}">
<img src="${book.cover}" alt="Cover" class="rounded me-3" style="width: 45px; height: 60px; object-fit: cover;"> <img src="${book.cover}" alt="Cover" class="rounded me-3" style="width: 45px; height: 60px; object-fit: cover;">
@ -198,37 +190,25 @@ function renderSelectedBooks() {
<h6 class="fw-bold mb-0 line-clamp-1">${book.title}</h6> <h6 class="fw-bold mb-0 line-clamp-1">${book.title}</h6>
<p class="text-muted small mb-0">${book.author}</p> <p class="text-muted small mb-0">${book.author}</p>
</div> </div>
<button type="button" class="btn btn-sm btn-outline-danger remove-book" onclick="removeBook(${id})"> <button type="button" class="btn btn-sm btn-outline-danger remove-book" onclick="removeBook(${id})"><i class="bi bi-trash"></i></button>
<i class="bi bi-trash"></i> </div>`;
</button>
</div>
`;
daftarBukuPinjamEl.insertAdjacentHTML('beforeend', itemHtml); daftarBukuPinjamEl.insertAdjacentHTML('beforeend', itemHtml);
hiddenInputsEl.insertAdjacentHTML('beforeend', `<input type="hidden" name="buku_ids[]" value="${id}">`);
const inputHtml = `<input type="hidden" name="buku_ids[]" value="${id}">`;
hiddenInputsEl.insertAdjacentHTML('beforeend', inputHtml);
}); });
counterBukuEl.textContent = `${selectedBookIds.size} Buku`; counterBukuEl.textContent = `${selectedBookIds.size} Buku`;
} }
// Fungsi search
const searchBukuInput = document.getElementById('searchBuku');
searchBukuInput.addEventListener('keyup', function() {
const searchTerm = this.value.toLowerCase();
document.querySelectorAll('.book-option').forEach(el => {
const title = el.dataset.bookTitle;
const author = el.dataset.bookAuthor;
if (title.includes(searchTerm) || author.includes(searchTerm)) {
el.style.display = 'block';
} else {
el.style.display = 'none';
}
});
});
// Global function untuk toggle selection // Global function untuk toggle selection
window.toggleBookSelection = function(itemElement, id) { window.toggleBookSelection = function(itemElement, id) {
const selectEl = document.getElementById('peminjam_id');
if(selectEl.value === "") {
alert("Silakan pilih Peminjam (Siswa/Guru) terlebih dahulu sebelum memilih buku!");
return;
}
const selectedOption = selectEl.options[selectEl.selectedIndex];
const roleUser = selectedOption.dataset.role;
const checkbox = itemElement.querySelector('.book-checkbox'); const checkbox = itemElement.querySelector('.book-checkbox');
const stringId = String(id); const stringId = String(id);
@ -237,8 +217,8 @@ function renderSelectedBooks() {
checkbox.checked = false; checkbox.checked = false;
itemElement.style.background = 'transparent'; itemElement.style.background = 'transparent';
} else { } else {
if (selectedBookIds.size >= MAX_BOOKS) { if (roleUser === 'siswa' && selectedBookIds.size >= MAX_BOOKS_SISWA) {
alert(`Maaf, Anda hanya dapat memilih maksimal ${MAX_BOOKS} buku.`); alert(`Maaf, role Siswa hanya dapat meminjam maksimal ${MAX_BOOKS_SISWA} buku secara bersamaan.`);
return; return;
} }
@ -249,39 +229,76 @@ function renderSelectedBooks() {
renderSelectedBooks(); renderSelectedBooks();
} }
// Global function untuk remove
window.removeBook = function(id) { window.removeBook = function(id) {
const stringId = String(id); selectedBookIds.delete(String(id));
selectedBookIds.delete(stringId); const itemElement = document.querySelector(`.book-option[data-book-id="${id}"] .book-item-list`);
const itemElement = document.querySelector(
`.book-option[data-book-id="${id}"] .book-item-list`);
if (itemElement) { if (itemElement) {
itemElement.querySelector('.book-checkbox').checked = false; itemElement.querySelector('.book-checkbox').checked = false;
itemElement.style.background = 'transparent'; itemElement.style.background = 'transparent';
} }
renderSelectedBooks(); renderSelectedBooks();
} }
const form = document.getElementById('formPeminjaman'); // Pencarian
form.reset(); document.getElementById('searchBuku').addEventListener('keyup', function() {
const searchTerm = this.value.toLowerCase();
tomSelect.clear(); document.querySelectorAll('.book-option').forEach(el => {
const title = el.dataset.bookTitle;
tglPinjam.setDate("today", false); const author = el.dataset.bookAuthor;
tglKembali.setDate(new Date().fp_incr(7), false); el.style.display = (title.includes(searchTerm) || author.includes(searchTerm)) ? 'block' : 'none';
});
selectedBookIds.clear();
document.querySelectorAll('.book-option').forEach(el => {
el.querySelector('.book-checkbox').checked = false;
el.querySelector('.book-item-list').style.background = 'transparent';
}); });
renderSelectedBooks(); document.getElementById('formPeminjaman').addEventListener('submit', function(e) {
e.preventDefault();
const peminjam = document.getElementById('peminjam_id').value;
const jumlahBuku = selectedBookIds.size;
// Validasi
if (!peminjam) {
Toast.fire({ icon: 'warning', title: 'Perhatian', text: 'Pilih peminjam terlebih dahulu!' });
return;
}
if (jumlahBuku === 0) {
Toast.fire({ icon: 'warning', title: 'Perhatian', text: 'Pilih minimal 1 buku!' });
return;
}
modernSwal.fire({
title: 'Proses Peminjaman?',
text: `Anda akan memproses ${jumlahBuku} buku.`,
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Ya, Proses',
cancelButtonText: 'Batal'
}).then((result) => {
if (result.isConfirmed) {
// Loading
modernSwal.fire({
title: 'Memproses...',
timer: 1000,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Transaksi peminjaman berhasil disimpan.'
});
setTimeout(() => {
window.location.href = "{{ route('admin.peminjaman.index') }}";
}, 1500);
});
}
});
});
document.getElementById('formPeminjaman').reset();
tomSelect.clear();
selectedBookIds.clear();
renderSelectedBooks();
}); });
</script> </script>
@endpush @endpush
</x-app-layout> </x-app-layout>

View File

@ -1,26 +1,34 @@
<x-app-layout> <x-app-layout>
@section('page-title', $pageTitle) @section('page-title', $pageTitle)
<div class="d-flex justify-content-between align-items-center mb-4"> <div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-3">
<div> <div>
<h3 class="my-0 fw-bold">Manajemen Peminjaman</h3> <h3 class="my-0 fw-bold">Manajemen Peminjaman</h3>
<p class="text-muted mb-0">Daftar ini hanya menampilkan buku yang masih berstatus "Dipinjam".</p> <p class="text-muted mb-0">Daftar ini hanya menampilkan buku yang masih berstatus "Dipinjam".</p>
</div> </div>
<a href="{{ route('admin.peminjaman.create') }}" class="btn btn-primary"> <div class="d-flex align-items-center gap-2">
<i class="bi bi-plus-circle-fill me-2"></i>Buat Peminjaman Manual <form action="#" method="GET" class="d-flex m-0 p-0 bg-white border rounded p-1" onsubmit="alert('Fitur download Excel sedang disiapkan tim Backend'); return false;">
</a> <input type="month" name="bulan_laporan" class="form-control form-control-sm border-0 me-1" required>
<button type="submit" class="btn btn-sm btn-success text-nowrap">
<i class="bi bi-file-earmark-excel-fill me-1"></i>Excel
</button>
</form>
<a href="{{ route('admin.peminjaman.create') }}" class="btn btn-primary text-nowrap">
<i class="bi bi-plus-circle-fill me-1"></i>Peminjaman Manual
</a>
</div>
</div> </div>
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
<table id="peminjamanTable" class="table table-striped table-hover nowrap dt-responsive" <table id="peminjamanTable" class="table table-striped table-hover nowrap dt-responsive" style="width:100%">
style="width:100%">
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<th>NO</th> <th>NO</th>
<th>ID PEMINJAMAN</th> <th>ID PEMINJAMAN</th>
<th>NAMA</th> <th>PEMINJAM (JABATAN/KELAS)</th>
<th>JUDUL BUKU</th> <th>JUDUL BUKU</th>
<th>TGL. PINJAM</th> <th>TGL. PINJAM</th>
<th>TENGGAT KEMBALI</th> <th>TENGGAT KEMBALI</th>
@ -41,10 +49,16 @@
$isHariIni = $now->startOfDay()->isSameDay($tenggat->startOfDay()); $isHariIni = $now->startOfDay()->isSameDay($tenggat->startOfDay());
$selisihHari = $now->startOfDay()->diffInDays($tenggat->startOfDay(), false); $selisihHari = $now->startOfDay()->diffInDays($tenggat->startOfDay(), false);
$isGuru = isset($transaksi['role']) && strtolower($transaksi['role']) == 'guru';
if ($isTerlambat) { if ($isTerlambat) {
$statusClass = 'badge rounded-pill bg-danger-subtle text-danger-emphasis'; if ($isGuru) {
$statusText = $statusClass = 'badge rounded-pill bg-info-subtle text-info-emphasis';
'Terlambat ' . $tenggat->startOfDay()->diffInDays($now->startOfDay()) . ' hari'; $statusText = 'Terlambat (Bebas Denda)';
} else {
$statusClass = 'badge rounded-pill bg-danger-subtle text-danger-emphasis';
$statusText = 'Terlambat ' . $tenggat->startOfDay()->diffInDays($now->startOfDay()) . ' hari';
}
} elseif ($isHariIni) { } elseif ($isHariIni) {
$statusClass = 'badge rounded-pill bg-warning-subtle text-warning-emphasis'; $statusClass = 'badge rounded-pill bg-warning-subtle text-warning-emphasis';
$statusText = 'Jatuh Tempo Hari Ini'; $statusText = 'Jatuh Tempo Hari Ini';
@ -57,8 +71,7 @@
<tr> <tr>
<td>{{ $counter++ }}</td> <td>{{ $counter++ }}</td>
<td> <td>
<span <span class="badge bg-primary-subtle text-primary fw-bold">{{ $transaksi['id_peminjaman'] }}</span>
class="badge bg-primary-subtle text-primary fw-bold">{{ $transaksi['id_peminjaman'] }}</span>
</td> </td>
<td> <td>
<div class="fw-bold">{{ $transaksi['peminjam'] }}</div> <div class="fw-bold">{{ $transaksi['peminjam'] }}</div>
@ -85,125 +98,104 @@ class="badge bg-primary-subtle text-primary fw-bold">{{ $transaksi['id_peminjama
</tr> </tr>
{{-- MODAL PENGEMBALIAN --}} {{-- MODAL PENGEMBALIAN --}}
<div class="modal fade" id="modalPengembalian-{{ $transaksi['id_peminjaman'] }}" <div class="modal fade" id="modalPengembalian-{{ $transaksi['id_peminjaman'] }}" tabindex="-1" aria-hidden="true">
tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered"> <div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content border-0 shadow-lg rounded-3"> <div class="modal-content border-0 shadow-lg rounded-3">
<div class="modal-header p-4"> <div class="modal-header p-4">
<h5 class="modal-title fw-bold">Proses Pengembalian <h5 class="modal-title fw-bold">Proses Pengembalian ({{ count($transaksi['books']) }} Buku)</h5>
({{ count($transaksi['books']) }} Buku) <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div> </div>
<div class="modal-body p-4"> <div class="modal-body p-4">
<div class="alert alert-light border mb-4"> <div class="alert alert-light border mb-4">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<span>Peminjam: <span>Peminjam: <strong>{{ $transaksi['peminjam'] }}</strong></span>
<strong>{{ $transaksi['peminjam'] }}</strong></span>
<span>ID: <strong>{{ $transaksi['id_peminjaman'] }}</strong></span> <span>ID: <strong>{{ $transaksi['id_peminjaman'] }}</strong></span>
</div> </div>
</div> </div>
<h6 class="fw-bold mb-3">Daftar Buku yang Dikembalikan:</h6> @if($isGuru)
<div class="alert alert-info py-2 small mb-3">
<i class="bi bi-shield-check me-1"></i> Role Guru: Bebas dari beban denda keterlambatan dan catatan denda/sanksi.
</div>
@endif
<h6 class="fw-bold mb-3">Daftar Buku yang Dikembalikan:</h6>
@foreach ($transaksi['books'] as $buku) @foreach ($transaksi['books'] as $buku)
<div class="card mb-3 border bg-light"> <div class="card mb-3 border bg-light">
<div class="card-body p-3"> <div class="card-body p-3">
<h6 class="fw-bold text-primary mb-2">{{ $buku['judul'] }}</h6> <h6 class="fw-bold text-primary mb-2">{{ $buku['judul'] }}</h6>
<div class="row"> <div class="row">
@if(!$isGuru)
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label small text-muted mb-1">Kondisi <label class="form-label small text-muted mb-1">Kondisi Buku</label>
Buku</label>
<div class="d-flex gap-3"> <div class="d-flex gap-3">
<div class="form-check"> <div class="form-check">
<input class="form-check-input radio-kondisi" <input class="form-check-input radio-kondisi" type="radio" name="kondisi_{{ $buku['id'] }}_{{ $transaksi['id_peminjaman'] }}" value="baik" checked>
type="radio" <label class="form-check-label small">Baik</label>
name="kondisi_{{ $buku['id'] }}_{{ $transaksi['id_peminjaman'] }}"
value="baik" checked>
<label
class="form-check-label small">Baik</label>
</div> </div>
<div class="form-check"> <div class="form-check">
<input class="form-check-input radio-kondisi" <input class="form-check-input radio-kondisi" type="radio" name="kondisi_{{ $buku['id'] }}_{{ $transaksi['id_peminjaman'] }}" value="rusak">
type="radio" <label class="form-check-label small">Rusak/Hilang</label>
name="kondisi_{{ $buku['id'] }}_{{ $transaksi['id_peminjaman'] }}"
value="rusak">
<label
class="form-check-label small">Rusak/Hilang</label>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6 denda-rusak-input-wrapper d-none"> <div class="col-md-6 denda-rusak-input-wrapper d-none">
<label class="form-label small text-muted mb-1">Denda <label class="form-label small text-muted mb-1">Denda Kerusakan</label>
Kerusakan</label> <input type="number" class="form-control form-control-sm denda-rusak-input" placeholder="0">
<input type="number"
class="form-control form-control-sm denda-rusak-input"
placeholder="0">
</div> </div>
<div class="col-12"> <div class="col-12">
<label class="form-label small text-muted mb-1"> <label class="form-label small text-muted mb-1"><i class="bi bi-pencil-square me-1"></i>Catatan Petugas</label>
<i class="bi bi-pencil-square me-1"></i>Catatan <textarea class="form-control form-control-sm" rows="2" placeholder="Contoh: Ada coretan di halaman 10, Cover sedikit terlipat..."></textarea>
Petugas
</label>
<textarea class="form-control form-control-sm" rows="2"
placeholder="Contoh: Ada coretan di halaman 10, Cover sedikit terlipat, dll..."></textarea>
</div> </div>
@else
<div class="col-12">
<span class="badge bg-success-subtle text-success-emphasis border"><i class="bi bi-check-circle me-1"></i> Buku dikembalikan oleh Guru</span>
</div>
@endif
</div> </div>
</div> </div>
</div> </div>
@endforeach @endforeach
<hr> <hr>
@if(!$isGuru)
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<span>Denda Keterlambatan ({{ $statusText }})</span> <span>Denda Keterlambatan ({{ $statusText }})</span>
@php @php
$dendaTelat = 0; $dendaTelat = 0;
if ($isTerlambat) { if ($isTerlambat && !$isGuru) {
$hari = $tenggat->startOfDay()->diffInDays($now->startOfDay()); $hari = $tenggat->startOfDay()->diffInDays($now->startOfDay());
$dendaTelat = $hari * 1000; $dendaTelat = $hari * 1000;
} }
@endphp @endphp
{{-- Data Attribute untuk JS --}} <strong class="text-danger denda-keterlambatan-display" data-denda-keterlambatan="{{ $dendaTelat }}">
<strong class="text-danger denda-keterlambatan-display"
data-denda-keterlambatan="{{ $dendaTelat }}">
Rp {{ number_format($dendaTelat, 0, ',', '.') }} Rp {{ number_format($dendaTelat, 0, ',', '.') }}
</strong> </strong>
</div> </div>
<div <div class="d-flex justify-content-between align-items-center mb-3 bg-danger bg-opacity-10 p-2 rounded">
class="d-flex justify-content-between align-items-center mb-3 bg-danger bg-opacity-10 p-2 rounded">
<span class="fw-bold text-danger">TOTAL YANG HARUS DIBAYAR</span> <span class="fw-bold text-danger">TOTAL YANG HARUS DIBAYAR</span>
<strong class="text-danger fs-5 total-denda-display"> <strong class="text-danger fs-5 total-denda-display">Rp {{ number_format($dendaTelat, 0, ',', '.') }}</strong>
Rp {{ number_format($dendaTelat, 0, ',', '.') }}
</strong>
</div> </div>
@endif
<div class="form-check form-switch mb-0"> <div class="form-check form-switch mb-0 mt-3">
<input class="form-check-input" type="checkbox" role="switch" checked <input class="form-check-input" type="checkbox" role="switch" checked id="waStrukToggle-{{ $transaksi['id_peminjaman'] }}">
id="waStrukToggle-{{ $transaksi['id_peminjaman'] }}"> <label class="form-check-label small" for="waStrukToggle-{{ $transaksi['id_peminjaman'] }}">
<label class="form-check-label small" Kirim <strong>Bukti Pengembalian</strong> ke WhatsApp
for="waStrukToggle-{{ $transaksi['id_peminjaman'] }}">
Kirim <strong>Bukti Pengembalian</strong> ke WhatsApp siswa
</label> </label>
</div> </div>
<div class="form-check form-switch mb-0"> <div class="form-check form-switch mb-0">
<input class="form-check-input email-toggle" type="checkbox" <input class="form-check-input email-toggle" type="checkbox" role="switch" checked id="emailStrukToggle-{{ $transaksi['id_peminjaman'] }}">
role="switch" checked <label class="form-check-label small" for="emailStrukToggle-{{ $transaksi['id_peminjaman'] }}">
id="emailStrukToggle-{{ $transaksi['id_peminjaman'] }}"> Kirim <strong>Bukti Pengembalian</strong> ke Email
<label class="form-check-label small"
for="emailStrukToggle-{{ $transaksi['id_peminjaman'] }}">
Kirim Bukti Pengembalian</strong> ke Email
</label> </label>
</div> </div>
</div> </div>
<div class="modal-footer p-3 bg-light"> <div class="modal-footer p-3 bg-light">
<button type="button" class="btn btn-outline-secondary" <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Batal</button>
data-bs-dismiss="modal">Batal</button> <button type="button" class="btn btn-primary btn-konfirmasi-kembali" data-nama-peminjam="{{ $transaksi['peminjam'] }}">
<button type="button" class="btn btn-primary btn-konfirmasi-kembali"
data-nama-peminjam="{{ $transaksi['peminjam'] }}"
data-nomor-hp="{{ $transaksi['nomor_hp'] }}">
Konfirmasi & Selesai Konfirmasi & Selesai
</button> </button>
</div> </div>
@ -211,9 +203,7 @@ class="d-flex justify-content-between align-items-center mb-3 bg-danger bg-opaci
</div> </div>
</div> </div>
@empty @empty
<tr> <tr><td colspan="8" class="text-center py-5">Tidak ada data.</td></tr>
<td colspan="8" class="text-center py-5">Tidak ada data.</td>
</tr>
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
@ -223,69 +213,49 @@ class="d-flex justify-content-between align-items-center mb-3 bg-danger bg-opaci
@push('scripts') @push('scripts')
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#peminjamanTable').DataTable({ $('#peminjamanTable').DataTable({ pageLength: 10, order: [[0, 'asc']] });
pageLength: 10,
order: [
[0, 'asc']
],
});
}); });
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
function formatRupiah(angka) { function formatRupiah(angka) {
return new Intl.NumberFormat('id-ID', { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0 }).format(angka).replace(/\s/g, '');
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0
}).format(angka).replace(/\s/g, '');
} }
function hitungTotalDenda(modal) { function hitungTotalDenda(modal) {
const dendaKeterlambatanEl = modal.querySelector('.denda-keterlambatan-display'); const dendaKeterlambatanEl = modal.querySelector('.denda-keterlambatan-display');
const dendaRusakInputs = modal.querySelectorAll('.denda-rusak-input');
const totalDendaEl = modal.querySelector('.total-denda-display'); const totalDendaEl = modal.querySelector('.total-denda-display');
if(!dendaKeterlambatanEl || !totalDendaEl) return;
let dendaKeterlambatan = parseInt(dendaKeterlambatanEl.dataset.dendaKeterlambatan) || 0; let dendaKeterlambatan = parseInt(dendaKeterlambatanEl.dataset.dendaKeterlambatan) || 0;
let totalDendaRusak = 0; let totalDendaRusak = 0;
dendaRusakInputs.forEach(input => { modal.querySelectorAll('.denda-rusak-input').forEach(input => {
if (!input.closest('.denda-rusak-input-wrapper').classList.contains('d-none')) { if (!input.closest('.denda-rusak-input-wrapper').classList.contains('d-none')) {
totalDendaRusak += parseInt(input.value) || 0; totalDendaRusak += parseInt(input.value) || 0;
} }
}); });
totalDendaEl.textContent = formatRupiah(dendaKeterlambatan + totalDendaRusak);
const totalDenda = dendaKeterlambatan + totalDendaRusak;
totalDendaEl.textContent = formatRupiah(totalDenda);
} }
// Logic Radio Button Kondisi Buku document.querySelectorAll('.radio-kondisi').forEach(radio => {
const radioKondisi = document.querySelectorAll('.radio-kondisi');
radioKondisi.forEach(radio => {
radio.addEventListener('change', function() { radio.addEventListener('change', function() {
const cardBody = this.closest('.card-body'); const cardBody = this.closest('.card-body');
const dendaRusakWrapper = cardBody.querySelector('.denda-rusak-input-wrapper'); const dendaRusakWrapper = cardBody.querySelector('.denda-rusak-input-wrapper');
const dendaRusakInput = cardBody.querySelector('.denda-rusak-input'); const dendaRusakInput = cardBody.querySelector('.denda-rusak-input');
if(this.value === 'rusak') {
const modal = this.closest('.modal');
if (this.value === 'rusak') {
dendaRusakWrapper.classList.remove('d-none'); dendaRusakWrapper.classList.remove('d-none');
} else { } else {
dendaRusakWrapper.classList.add('d-none'); dendaRusakWrapper.classList.add('d-none');
dendaRusakInput.value = 0; dendaRusakInput.value = 0;
} }
hitungTotalDenda(modal); hitungTotalDenda(this.closest('.modal'));
}); });
}); });
// Logic Input Denda Rusak document.querySelectorAll('.denda-rusak-input').forEach(input => {
const dendaRusakInputs = document.querySelectorAll('.denda-rusak-input'); input.addEventListener('input', function() { hitungTotalDenda(this.closest('.modal')); });
dendaRusakInputs.forEach(input => {
input.addEventListener('input', function() {
const modal = this.closest('.modal');
hitungTotalDenda(modal);
});
}); });
}); });
@ -296,54 +266,29 @@ function hitungTotalDenda(modal) {
const isEmailChecked = modalEl.find('.email-toggle').is(':checked'); const isEmailChecked = modalEl.find('.email-toggle').is(':checked');
modalInstance.hide(); modalInstance.hide();
modernSwal.fire({ modernSwal.fire({
title: 'Selesaikan Transaksi?', title: 'Selesaikan Transaksi?', text: `Buku dari ${nama} akan ditandai sudah kembali.`, icon: 'question',
text: `Buku dari ${nama} akan ditandai sudah kembali.`, showCancelButton: true, confirmButtonText: 'Ya, Selesaikan', cancelButtonText: 'Batal'
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Ya, Selesaikan',
cancelButtonText: 'Batal'
}).then((result) => { }).then((result) => {
if (result.isConfirmed) { if (result.isConfirmed) {
// Loading Simpan DB
modernSwal.fire({ modernSwal.fire({
title: 'Menyimpan Data...', title: 'Menyimpan Data...', timer: 800, timerProgressBar: true, didOpen: () => Swal.showLoading()
timer: 800,
timerProgressBar: true,
didOpen: () => Swal.showLoading()
}).then(() => { }).then(() => {
// Loading Kirim Email (Jika dicentang)
if (isEmailChecked) { if (isEmailChecked) {
const dummyEmail = nama.replace(/\s+/g, '.').toLowerCase() + const dummyEmail = nama.replace(/\s+/g, '.').toLowerCase() + '@sekolah.sch.id';
'@sekolah.sch.id';
modernSwal.fire({ modernSwal.fire({
title: 'Mengirim Email...', title: 'Mengirim Email...', html: `Mengirim nota ke: <b>${dummyEmail}</b>`, timer: 2000, timerProgressBar: true, didOpen: () => Swal.showLoading()
html: `Mengirim nota ke: <b>${dummyEmail}</b>`, }).then(() => { finishTransaction(true); });
timer: 2000, } else { finishTransaction(false); }
timerProgressBar: true,
didOpen: () => Swal.showLoading()
}).then(() => {
finishTransaction(true);
});
} else {
finishTransaction(false);
}
}); });
} else { } else { modalInstance.show(); }
modalInstance.show();
}
}); });
function finishTransaction(withEmail) { function finishTransaction(withEmail) {
Toast.fire({ Toast.fire({ icon: 'success', title: 'Berhasil', text: withEmail ? 'Buku kembali & Email terkirim.' : 'Buku berhasil dikembalikan.' });
icon: 'success',
title: 'Berhasil',
text: withEmail ? 'Buku kembali & Email terkirim.' : 'Buku berhasil dikembalikan.'
});
setTimeout(() => location.reload(), 1500); setTimeout(() => location.reload(), 1500);
} }
}); });
</script> </script>
@endpush @endpush
</x-app-layout> </x-app-layout>

View File

@ -11,53 +11,50 @@
<div class="col-md-10"> <div class="col-md-10">
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<form action="{{ route('admin.pengguna.store') }}" method="POST"> <form action="{{ route('admin.pengguna.store') }}" method="POST" id="formPengguna">
@csrf @csrf
<div class="mb-3"> <div class="mb-3">
<label for="role" class="form-label">Role <span class="text-danger">*</span></label> <label for="role" class="form-label">Role <span class="text-danger">*</span></label>
<select class="form-select @error('role') is-invalid @enderror" id="role" <select class="form-select @error('role') is-invalid @enderror" id="role" name="role"
name="role" required onchange="toggleFields()"> required onchange="toggleFields()">
<option value="" selected disabled>Pilih role terlebih dahulu...</option> <option value="" selected disabled>Pilih role terlebih dahulu...</option>
<option value="siswa" {{ old('role') == 'siswa' ? 'selected' : '' }}>Siswa</option> <option value="siswa" {{ old('role')=='siswa' ? 'selected' : '' }}>Siswa</option>
<option value="guru" {{ old('role') == 'guru' ? 'selected' : '' }}>Guru</option> <option value="guru" {{ old('role')=='guru' ? 'selected' : '' }}>Guru</option>
<option value="penjaga perpus" {{ old('role') == 'penjaga perpus' ? 'selected' : '' }}> <option value="penjaga perpus" {{ old('role')=='penjaga perpus' ? 'selected' : '' }}>
Penjaga Perpustakaan</option> Penjaga Perpustakaan</option>
</select> </select>
@error('role') @error('role')
<div class="invalid-feedback">{{ $message }}</div> <div class="invalid-feedback">{{ $message }}</div>
@enderror @enderror
</div> </div>
{{-- Bagian Form Dinamis --}} {{-- Bagian Form Dinamis --}}
<div id="dynamic-form" class="d-none"> <div id="dynamic-form" class="d-none">
{{-- Nama Lengkap --}}
<div class="mb-3"> <div class="mb-3">
<label for="nama_lengkap" class="form-label">Nama Lengkap</label> <label for="nama_lengkap" class="form-label">Nama Lengkap</label>
<input type="text" class="form-control @error('nama_lengkap') is-invalid @enderror" <input type="text" class="form-control @error('nama_lengkap') is-invalid @enderror"
id="nama_lengkap" name="nama_lengkap" value="{{ old('nama_lengkap') }}" required> id="nama_lengkap" name="nama_lengkap" value="{{ old('nama_lengkap') }}" required>
</div> </div>
{{-- Identitas Unik (NISN/NIP) --}}
<div class="mb-3"> <div class="mb-3">
<label for="nomor_induk" class="form-label" id="label_nomor_induk">NISN / NIP</label> <label for="nomor_induk" class="form-label" id="label_nomor_induk">NISN / NIP</label>
<input type="number" class="form-control @error('nomor_induk') is-invalid @enderror" <input type="number" class="form-control @error('nomor_induk') is-invalid @enderror"
id="nomor_induk" name="nomor_induk" value="{{ old('nomor_induk') }}" id="nomor_induk" name="nomor_induk" value="{{ old('nomor_induk') }}"
placeholder="Masukkan Nomor Induk"> placeholder="Masukkan Nomor Induk">
@error('nomor_induk') @error('nomor_induk')
<div class="invalid-feedback">{{ $message }}</div> <div class="invalid-feedback">{{ $message }}</div>
@enderror @enderror
</div> </div>
{{-- Kontak (Email & HP) --}}
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="email" class="form-label">Email</label> <label for="email" class="form-label">Email</label>
<input type="email" class="form-control @error('email') is-invalid @enderror" <input type="email" class="form-control @error('email') is-invalid @enderror"
id="email" name="email" value="{{ old('email') }}" required> id="email" name="email" value="{{ old('email') }}" required>
@error('email') @error('email')
<div class="invalid-feedback">{{ $message }}</div> <div class="invalid-feedback">{{ $message }}</div>
@enderror @enderror
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
@ -67,7 +64,6 @@
</div> </div>
</div> </div>
{{-- Field Khusus Siswa (Kelas & Golongan) --}}
<div class="row" id="field_siswa_only" style="display: none;"> <div class="row" id="field_siswa_only" style="display: none;">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="kelas" class="form-label">Kelas</label> <label for="kelas" class="form-label">Kelas</label>
@ -83,12 +79,9 @@
<hr> <hr>
{{-- Keamanan (Password) --}}
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="password" class="form-label"> <label for="password" class="form-label">Password</label>
Password
</label>
<div class="input-group has-validation"> <div class="input-group has-validation">
<input type="password" <input type="password"
class="form-control @error('password') is-invalid @enderror" id="password" class="form-control @error('password') is-invalid @enderror" id="password"
@ -98,7 +91,7 @@ class="form-control @error('password') is-invalid @enderror" id="password"
<i class="bi bi-eye" id="icon-password"></i> <i class="bi bi-eye" id="icon-password"></i>
</button> </button>
@error('password') @error('password')
<div class="invalid-feedback">{{ $message }}</div> <div class="invalid-feedback">{{ $message }}</div>
@enderror @enderror
</div> </div>
</div> </div>
@ -126,21 +119,17 @@ class="form-control @error('password') is-invalid @enderror" id="password"
</div> </div>
</div> </div>
@push('scripts')
<script> <script>
function toggleFields() { function toggleFields() {
const role = document.getElementById('role').value; const role = document.getElementById('role').value;
const dynamicForm = document.getElementById('dynamic-form'); const dynamicForm = document.getElementById('dynamic-form');
const labelInduk = document.getElementById('label_nomor_induk'); const labelInduk = document.getElementById('label_nomor_induk');
const inputInduk = document.getElementById('nomor_induk'); const inputInduk = document.getElementById('nomor_induk');
const fieldSiswaOnly = document.getElementById('field_siswa_only'); const fieldSiswaOnly = document.getElementById('field_siswa_only');
// Tampilkan form if (role) dynamicForm.classList.remove('d-none');
if (role) {
dynamicForm.classList.remove('d-none');
}
// Atur Label & Field berdasarkan Role
if (role === 'siswa') { if (role === 'siswa') {
labelInduk.innerHTML = 'NISN <span class="text-danger">*</span>'; labelInduk.innerHTML = 'NISN <span class="text-danger">*</span>';
inputInduk.placeholder = 'Masukkan NISN Siswa'; inputInduk.placeholder = 'Masukkan NISN Siswa';
@ -156,9 +145,7 @@ function toggleFields() {
} }
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', toggleFields);
toggleFields();
});
document.querySelectorAll('.toggle-password').forEach(function(button) { document.querySelectorAll('.toggle-password').forEach(function(button) {
button.addEventListener('click', function() { button.addEventListener('click', function() {
@ -167,15 +154,24 @@ function toggleFields() {
const icon = document.getElementById('icon-' + targetId); const icon = document.getElementById('icon-' + targetId);
if (input.type === 'password') { if (input.type === 'password') {
input.type = 'text'; input.type = 'text'; icon.classList.replace('bi-eye', 'bi-eye-slash');
icon.classList.remove('bi-eye');
icon.classList.add('bi-eye-slash');
} else { } else {
input.type = 'password'; input.type = 'password'; icon.classList.replace('bi-eye-slash', 'bi-eye');
icon.classList.remove('bi-eye-slash');
icon.classList.add('bi-eye');
} }
}); });
}); });
document.getElementById('formPengguna').addEventListener('submit', function() {
modernSwal.fire({
title: 'Menyimpan Data...',
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
});
@if(session('success'))
Toast.fire({ icon: 'success', title: 'Berhasil', text: '{{ session("success") }}' });
@endif
</script> </script>
</x-app-layout> @endpush
</x-app-layout>

View File

@ -11,9 +11,9 @@
<div class="col-md-10"> <div class="col-md-10">
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<form action="{{ route('admin.pengguna.update', $pengguna->id) }}" method="POST"> <form action="{{ route('admin.pengguna.update', $pengguna->id) }}" method="POST" id="formEditPengguna">
@csrf @csrf
@method('PUT') @method('PATCH')
<div class="mb-3"> <div class="mb-3">
<label for="role" class="form-label">Role <span class="text-danger">*</span></label> <label for="role" class="form-label">Role <span class="text-danger">*</span></label>
@ -25,28 +25,21 @@
@error('role') <div class="invalid-feedback">{{ $message }}</div> @enderror @error('role') <div class="invalid-feedback">{{ $message }}</div> @enderror
</div> </div>
{{-- Bagian Form Dinamis --}}
<div id="dynamic-form"> <div id="dynamic-form">
{{-- Nama Lengkap --}}
<div class="mb-3"> <div class="mb-3">
<label for="nama_lengkap" class="form-label">Nama Lengkap</label> <label for="nama_lengkap" class="form-label">Nama Lengkap</label>
<input type="text" class="form-control @error('nama_lengkap') is-invalid @enderror" <input type="text" class="form-control @error('nama_lengkap') is-invalid @enderror"
id="nama_lengkap" name="nama_lengkap" value="{{ old('nama_lengkap', $pengguna->name) }}" required> id="nama_lengkap" name="nama_lengkap" value="{{ old('nama_lengkap', $pengguna->name) }}" required>
</div> </div>
{{-- Identitas Unik (NISN/NIP) --}}
<div class="mb-3"> <div class="mb-3">
@php @php $oldNomorInduk = old('nomor_induk', $pengguna->role == 'siswa' ? $pengguna->nisn : $pengguna->nip); @endphp
$oldNomorInduk = old('nomor_induk', $pengguna->role == 'siswa' ? $pengguna->nisn : $pengguna->nip);
@endphp
<label for="nomor_induk" class="form-label" id="label_nomor_induk">NISN / NIP</label> <label for="nomor_induk" class="form-label" id="label_nomor_induk">NISN / NIP</label>
<input type="number" class="form-control @error('nomor_induk') is-invalid @enderror" <input type="number" class="form-control @error('nomor_induk') is-invalid @enderror"
id="nomor_induk" name="nomor_induk" value="{{ $oldNomorInduk }}" placeholder="Masukkan Nomor Induk"> id="nomor_induk" name="nomor_induk" value="{{ $oldNomorInduk }}" placeholder="Masukkan Nomor Induk">
@error('nomor_induk') <div class="invalid-feedback fw-bold">{{ $message }}</div> @enderror @error('nomor_induk') <div class="invalid-feedback fw-bold">{{ $message }}</div> @enderror
</div> </div>
{{-- Kontak (Email & HP) --}}
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="email" class="form-label">Email</label> <label for="email" class="form-label">Email</label>
@ -56,25 +49,23 @@
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="no_hp" class="form-label">No. Handphone</label> <label for="no_hp" class="form-label">No. Handphone</label>
<input type="text" class="form-control" id="no_hp" name="no_hp" value="{{ old('no_hp', $pengguna->no_hp) }}" placeholder="Contoh: 08123456789"> <input type="text" class="form-control" id="no_hp" name="no_hp" value="{{ old('no_hp', $pengguna->no_hp) }}">
</div> </div>
</div> </div>
{{-- Field Khusus Siswa (Kelas & Golongan) --}}
<div class="row" id="field_siswa_only" style="display: none;"> <div class="row" id="field_siswa_only" style="display: none;">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="kelas" class="form-label">Kelas</label> <label for="kelas" class="form-label">Kelas</label>
<input type="text" class="form-control" id="kelas" name="kelas" value="{{ old('kelas', $pengguna->kelas) }}" placeholder="Contoh: XII RPL 1"> <input type="text" class="form-control" id="kelas" name="kelas" value="{{ old('kelas', $pengguna->kelas) }}">
</div> </div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="golongan" class="form-label">Golongan</label> <label for="golongan" class="form-label">Golongan</label>
<input type="text" class="form-control" id="golongan" name="golongan" value="{{ old('golongan', $pengguna->golongan) }}" placeholder="Contoh: A/B"> <input type="text" class="form-control" id="golongan" name="golongan" value="{{ old('golongan', $pengguna->golongan) }}">
</div> </div>
</div> </div>
<hr> <hr>
{{-- Keamanan (Password) --}}
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<label for="password" class="form-label">Password Baru <span class="small text-muted">(opsional)</span></label> <label for="password" class="form-label">Password Baru <span class="small text-muted">(opsional)</span></label>
@ -97,6 +88,7 @@
</div> </div>
</div> </div>
@push('scripts')
<script> <script>
function toggleFields() { function toggleFields() {
const role = document.getElementById('role').value; const role = document.getElementById('role').value;
@ -104,7 +96,6 @@ function toggleFields() {
const inputInduk = document.getElementById('nomor_induk'); const inputInduk = document.getElementById('nomor_induk');
const fieldSiswaOnly = document.getElementById('field_siswa_only'); const fieldSiswaOnly = document.getElementById('field_siswa_only');
// Atur Label & Field berdasarkan Role
if (role === 'siswa') { if (role === 'siswa') {
labelInduk.innerHTML = 'NISN <span class="text-danger">*</span>'; labelInduk.innerHTML = 'NISN <span class="text-danger">*</span>';
inputInduk.placeholder = 'Masukkan NISN Siswa'; inputInduk.placeholder = 'Masukkan NISN Siswa';
@ -119,9 +110,19 @@ function toggleFields() {
fieldSiswaOnly.style.display = 'none'; fieldSiswaOnly.style.display = 'none';
} }
} }
document.addEventListener('DOMContentLoaded', toggleFields);
document.addEventListener('DOMContentLoaded', function() { document.getElementById('formEditPengguna').addEventListener('submit', function() {
toggleFields(); modernSwal.fire({
title: 'Menyimpan Perubahan...',
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
}); });
@if(session('success'))
Toast.fire({ icon: 'success', title: 'Berhasil', text: '{{ session("success") }}' });
@endif
</script> </script>
@endpush
</x-app-layout> </x-app-layout>

View File

@ -1,17 +1,29 @@
<x-app-layout> <x-app-layout>
@section('page-title', content: 'Manajemen Pengguna') @section('page-title', 'Manajemen Pengguna')
<div class="container-fluid p-0"> <div class="container-fluid p-0">
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="h3 text-gray-800">{{ $pageTitle }}</h1> <h1 class="h3 text-gray-800">{{ $pageTitle ?? 'Manajemen Pengguna' }}</h1>
</div> </div>
<div class="card shadow mb-5"> <div class="card shadow mb-5">
<div class="card-header py-3 d-flex justify-content-between align-items-center"> <div class="card-header py-3 d-flex justify-content-between align-items-center flex-wrap gap-2">
<h6 class="m-0 font-weight-bold text-primary">Daftar Pengguna Aktif</h6> <h6 class="m-0 font-weight-bold text-primary">Daftar Pengguna Aktif</h6>
<a href="{{ route('admin.pengguna.create') }}" class="btn btn-primary">
<i class="bi bi-plus-circle-fill me-2"></i>Tambah Pengguna <div class="d-flex align-items-center">
</a> <form action="{{ route('admin.pengguna.index') }}" method="GET" class="me-2 mb-0">
<select name="role" class="form-select form-select-sm" onchange="this.form.submit()">
<option value="">Semua Kategori</option>
<option value="siswa" {{ request('role') == 'siswa' ? 'selected' : '' }}>Siswa</option>
<option value="guru" {{ request('role') == 'guru' ? 'selected' : '' }}>Guru</option>
<option value="penjaga perpus" {{ request('role') == 'penjaga perpus' ? 'selected' : '' }}>Petugas</option>
</select>
</form>
<a href="{{ route('admin.pengguna.create') }}" class="btn btn-sm btn-primary">
<i class="bi bi-plus-circle-fill me-1"></i>Tambah Pengguna
</a>
</div>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
@ -56,15 +68,13 @@
@endif @endif
</td> </td>
<td class="text-center"> <td class="text-center">
<a href="{{ route('admin.pengguna.edit', $user->id) }}" <a href="{{ route('admin.pengguna.edit', $user->id) }}" class="btn btn-sm btn-warning">
class="btn btn-sm btn-warning">
<i class="bi bi-pencil"></i> Edit <i class="bi bi-pencil"></i> Edit
</a> </a>
<form action="{{ route('admin.pengguna.destroy', $user->id) }}" method="POST" <form action="{{ route('admin.pengguna.destroy', $user->id) }}" method="POST" class="d-inline form-delete-user" data-nama="{{ $user->name }}">
class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
@csrf @csrf
@method('DELETE') @method('DELETE')
<button class="btn btn-sm btn-danger"><i class="bi bi-trash"></i></button> <button type="button" class="btn btn-sm btn-danger btn-hapus"><i class="bi bi-trash"></i></button>
</form> </form>
</td> </td>
</tr> </tr>
@ -75,8 +85,6 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
@endforelse @endforelse
</tbody> </tbody>
</table> </table>
{{-- Pagination --}}
<div class="mt-3"> <div class="mt-3">
{{ $users->links() }} {{ $users->links() }}
</div> </div>
@ -89,12 +97,9 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
{{-- BAGIAN DATA INDUK (WHITELIST) --}} {{-- BAGIAN DATA INDUK (WHITELIST) --}}
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<div> <div>
<h4 class="fw-bold text-success mb-1"> <h4 class="fw-bold text-success mb-1"><i class="bi bi-database-lock me-2"></i>Data Induk (Whitelist)</h4>
<i class="bi bi-database-lock me-2"></i>Data Induk (Whitelist)
</h4>
<p class="text-muted mb-0">Daftar NIP/NISN yang <b>diizinkan</b> untuk mendaftar.</p> <p class="text-muted mb-0">Daftar NIP/NISN yang <b>diizinkan</b> untuk mendaftar.</p>
</div> </div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalMasterInduk"> <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalMasterInduk">
<i class="bi bi-plus-lg me-1"></i> Tambah Data Induk <i class="bi bi-plus-lg me-1"></i> Tambah Data Induk
</button> </button>
@ -131,28 +136,19 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
</td> </td>
<td class="text-center"> <td class="text-center">
@php @php
$isRegistered = \App\Models\User::where('nisn', $item->nomor_induk) $isRegistered = \App\Models\User::where('nisn', $item->nomor_induk)->orWhere('nip', $item->nomor_induk)->exists();
->orWhere('nip', $item->nomor_induk)
->exists();
@endphp @endphp
@if ($isRegistered) @if ($isRegistered)
<span class="badge bg-success text-white"> <span class="badge bg-success text-white"><i class="bi bi-check-circle-fill me-1"></i>Terdaftar</span>
<i class="bi bi-check-circle-fill me-1"></i>Terdaftar
</span>
@else @else
<span class="badge bg-warning text-dark"> <span class="badge bg-warning text-dark"><i class="bi bi-hourglass-split me-1"></i>Belum Daftar</span>
<i class="bi bi-hourglass-split me-1"></i>Belum Daftar
</span>
@endif @endif
</td> </td>
<td class="text-end"> <td class="text-end">
<form action="{{ route('admin.master-induk.destroy', $item->id) }}" <form action="{{ route('admin.master-induk.destroy', $item->id) }}" method="POST" class="d-inline form-delete-whitelist" data-induk="{{ $item->nomor_induk }}">
method="POST"
onsubmit="return confirm('Hapus data ini? User dengan NIP/NISN ini tidak akan bisa daftar lagi.');">
@csrf @csrf
@method('DELETE') @method('DELETE')
<button type="submit" class="btn btn-sm btn-outline-danger"> <button type="button" class="btn btn-sm btn-outline-danger btn-hapus-whitelist">
<i class="bi bi-trash"></i> Hapus <i class="bi bi-trash"></i> Hapus
</button> </button>
</form> </form>
@ -160,9 +156,7 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="6" class="text-center py-4 text-muted"> <td colspan="6" class="text-center py-4 text-muted">Belum ada data whitelist. Silakan tambah data.</td>
Belum ada data whitelist. Silakan tambah data.
</td>
</tr> </tr>
@endforelse @endforelse
</tbody> </tbody>
@ -170,7 +164,6 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{-- MODAL TAMBAH DATA INDUK --}} {{-- MODAL TAMBAH DATA INDUK --}}
@ -181,14 +174,14 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
<h5 class="modal-title fw-bold">Tambah Whitelist (NIP/NISN)</h5> <h5 class="modal-title fw-bold">Tambah Whitelist (NIP/NISN)</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button> <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div> </div>
<form action="{{ route('admin.master-induk.store') }}" method="POST"> {{-- FORM TAMBAH WHITELIST --}}
<form action="{{ route('admin.master-induk.store') }}" method="POST" id="formWhitelist">
@csrf @csrf
<div class="modal-body"> <div class="modal-body">
<div class="alert alert-info small mb-3"> <div class="alert alert-info small mb-3">
<i class="bi bi-info-circle-fill me-1"></i> <i class="bi bi-info-circle-fill me-1"></i>
Masukkan data siswa/guru yang valid agar mereka bisa mendaftar. Masukkan data siswa/guru yang valid agar mereka bisa mendaftar.
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Role</label> <label class="form-label">Role</label>
<select name="role" class="form-select" required> <select name="role" class="form-select" required>
@ -197,17 +190,13 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
<option value="penjaga perpus">Petugas Perpustakaan</option> <option value="penjaga perpus">Petugas Perpustakaan</option>
</select> </select>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">NIP / NISN</label> <label class="form-label">NIP / NISN</label>
<input type="number" name="nomor_induk" class="form-control" <input type="number" name="nomor_induk" class="form-control" placeholder="Contoh: 1234567890" required>
placeholder="Contoh: 1234567890" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Nama Pemilik</label> <label class="form-label">Nama Pemilik</label>
<input type="text" name="nama_pemilik" class="form-control" <input type="text" name="nama_pemilik" class="form-control" placeholder="Nama Siswa/Guru..." required>
placeholder="Nama Siswa/Guru..." required>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
@ -218,4 +207,56 @@ class="d-inline" onsubmit="return confirm('Yakin hapus user ini?')">
</div> </div>
</div> </div>
</div> </div>
@push('scripts')
<script>
$(document).ready(function() {
$('.btn-hapus').on('click', function(e) {
e.preventDefault();
let form = $(this).closest('form');
let nama = form.data('nama');
modernSwal.fire({
title: 'Hapus Pengguna?',
text: `Apakah Anda yakin ingin menghapus akun milik ${nama}?`,
icon: 'warning',
showCancelButton: true, confirmButtonText: 'Ya, Hapus', cancelButtonText: 'Batal', confirmButtonColor: '#dc3545'
}).then((result) => {
if (result.isConfirmed) {
modernSwal.fire({ title: 'Menghapus...', allowOutsideClick: false, didOpen: () => Swal.showLoading() });
form.submit();
}
});
});
$('.btn-hapus-whitelist').on('click', function(e) {
e.preventDefault();
let form = $(this).closest('form');
let induk = form.data('induk');
modernSwal.fire({
title: 'Hapus Data Induk?',
text: `Data dengan nomor ${induk} tidak akan bisa mendaftar lagi.`,
icon: 'warning',
showCancelButton: true, confirmButtonText: 'Ya, Hapus', cancelButtonText: 'Batal', confirmButtonColor: '#dc3545'
}).then((result) => {
if (result.isConfirmed) {
modernSwal.fire({ title: 'Menghapus...', allowOutsideClick: false, didOpen: () => Swal.showLoading() });
form.submit();
}
});
});
$('#formWhitelist').on('submit', function() {
modernSwal.fire({ title: 'Menyimpan...', allowOutsideClick: false, didOpen: () => Swal.showLoading() });
});
});
@if(session('success'))
document.addEventListener('DOMContentLoaded', function() {
Toast.fire({ icon: 'success', title: 'Berhasil', text: '{{ session("success") }}' });
});
@endif
</script>
@endpush
</x-app-layout> </x-app-layout>

View File

@ -1,7 +1,7 @@
<x-app-layout> <x-app-layout>
@section('page-title', $pageTitle) @section('page-title', $pageTitle)
<div class="d-flex align-items-center mb-4"> <div class="d-flex align-items-center mb-4">
<a href="{{ route('admin.pengguna.index') }}" class="btn btn-outline-secondary me-3"> <a href="{{ route('admin.pengumuman.index') }}" class="btn btn-outline-secondary me-3">
<i class="bi bi-arrow-left"></i> <i class="bi bi-arrow-left"></i>
</a> </a>
<h3 class="my-0 fw-bold">Formulir Tambah Pengumuman</h3> <h3 class="my-0 fw-bold">Formulir Tambah Pengumuman</h3>
@ -12,17 +12,16 @@
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<div class="card-body"> <div class="card-body">
<form action="#" method="POST"> <form action="#" method="POST" id="formTambahPengumuman">
{{-- Form ini tidak akan berfungsi karena tidak ada backend --}}
<div class="mb-3"> <div class="mb-3">
<label for="judul" class="form-label">Judul Pengumuman</label> <label for="judul" class="form-label">Judul Pengumuman</label>
<input type="text" class="form-control" id="judul" <input type="text" class="form-control" id="judul"
placeholder="Masukkan judul pengumuman"> placeholder="Masukkan judul pengumuman" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="tipe" class="form-label">Tipe Pengumuman</label> <label for="tipe" class="form-label">Tipe Pengumuman</label>
<select class="form-select" id="tipe"> <select class="form-select" id="tipe" required>
<option selected>Pilih tipe...</option> <option value="" selected disabled>Pilih tipe...</option>
<option value="info">Info</option> <option value="info">Info</option>
<option value="success">Success</option> <option value="success">Success</option>
<option value="warning">Warning</option> <option value="warning">Warning</option>
@ -32,7 +31,7 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="content" class="form-label">Isi Pengumuman</label> <label for="content" class="form-label">Isi Pengumuman</label>
<textarea class="form-control" id="content" rows="5" placeholder="Tulis isi pengumuman di sini..."></textarea> <textarea class="form-control" id="content" rows="5" placeholder="Tulis isi pengumuman di sini..." required></textarea>
</div> </div>
<hr> <hr>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
@ -44,4 +43,28 @@
</div> </div>
</div> </div>
</div> </div>
</x-app-layout>
@push('scripts')
<script>
document.getElementById('formTambahPengumuman').addEventListener('submit', function(e) {
e.preventDefault();
modernSwal.fire({
title: 'Menyimpan...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Pengumuman baru berhasil ditambahkan.'
});
setTimeout(() => {
window.location.href = "{{ route('admin.pengumuman.index') }}";
}, 1500);
});
});
</script>
@endpush
</x-app-layout>

View File

@ -1,7 +1,7 @@
<x-app-layout> <x-app-layout>
@section('page-title', $pageTitle) @section('page-title', $pageTitle)
<div class="d-flex align-items-center mb-4"> <div class="d-flex align-items-center mb-4">
<a href="{{ route('admin.pengguna.index') }}" class="btn btn-outline-secondary me-3"> <a href="{{ route('admin.pengumuman.index') }}" class="btn btn-outline-secondary me-3">
<i class="bi bi-arrow-left"></i> <i class="bi bi-arrow-left"></i>
</a> </a>
<h3 class="my-0 fw-bold">Formulir Edit Pengumuman</h3> <h3 class="my-0 fw-bold">Formulir Edit Pengumuman</h3>
@ -12,32 +12,26 @@
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<div class="card-body"> <div class="card-body">
<form action="#" method="POST"> <form action="#" method="POST" id="formEditPengumuman">
{{-- Form ini tidak akan berfungsi karena tidak ada backend --}}
<div class="mb-3"> <div class="mb-3">
<label for="judul" class="form-label">Judul Pengumuman</label> <label for="judul" class="form-label">Judul Pengumuman</label>
<input type="text" class="form-control" id="judul" <input type="text" class="form-control" id="judul"
value="{{ $pengumuman['title'] }}"> value="{{ $pengumuman['title'] }}" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="tipe" class="form-label">Tipe Pengumuman</label> <label for="tipe" class="form-label">Tipe Pengumuman</label>
<select class="form-select" id="tipe"> <select class="form-select" id="tipe" required>
<option>Pilih tipe...</option> <option value="" disabled>Pilih tipe...</option>
<option value="info" @if ($pengumuman['type'] == 'info') selected @endif>Info <option value="info" @if ($pengumuman['type'] == 'info') selected @endif>Info</option>
</option> <option value="success" @if ($pengumuman['type'] == 'success') selected @endif>Success</option>
<option value="success" @if ($pengumuman['type'] == 'success') selected @endif>Success <option value="warning" @if ($pengumuman['type'] == 'warning') selected @endif>Warning</option>
</option> <option value="danger" @if ($pengumuman['type'] == 'danger') selected @endif>Danger</option>
<option value="warning" @if ($pengumuman['type'] == 'warning') selected @endif>Warning <option value="secondary" @if ($pengumuman['type'] == 'secondary') selected @endif>Secondary</option>
</option>
<option value="danger" @if ($pengumuman['type'] == 'danger') selected @endif>Danger
</option>
<option value="secondary" @if ($pengumuman['type'] == 'secondary') selected @endif>
Secondary</option>
</select> </select>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="content" class="form-label">Isi Pengumuman</label> <label for="content" class="form-label">Isi Pengumuman</label>
<textarea class="form-control" id="content" rows="5">{{ $pengumuman['content'] }}</textarea> <textarea class="form-control" id="content" rows="5" required>{{ $pengumuman['content'] }}</textarea>
</div> </div>
<hr> <hr>
<div class="d-flex justify-content-end"> <div class="d-flex justify-content-end">
@ -49,4 +43,29 @@
</div> </div>
</div> </div>
</div> </div>
</x-app-layout>
@push('scripts')
<script>
document.getElementById('formEditPengumuman').addEventListener('submit', function(e) {
e.preventDefault();
modernSwal.fire({
title: 'Menyimpan Perubahan...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Pengumuman berhasil diperbarui.'
});
// Redirect setelah 1.5 detik
setTimeout(() => {
window.location.href = "{{ route('admin.pengumuman.index') }}";
}, 1500);
});
});
</script>
@endpush
</x-app-layout>

View File

@ -17,13 +17,13 @@
<th scope="col">Tipe</th> <th scope="col">Tipe</th>
<th scope="col">Judul</th> <th scope="col">Judul</th>
<th scope="col">Isi</th> <th scope="col">Isi</th>
<th scope="col">Aksi</th> <th scope="col" class="text-center">Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@forelse ($semuaPengumuman as $item) @forelse ($semuaPengumuman as $item)
<tr> <tr>
<td>{{ $loop->iteration }}</td> <td class="row-number">{{ $loop->iteration }}</td>
<td> <td>
<span class="badge bg-{{ $item['type'] }}-subtle text-{{ $item['type'] }}-emphasis">{{ Str::title($item['type']) }}</span> <span class="badge bg-{{ $item['type'] }}-subtle text-{{ $item['type'] }}-emphasis">{{ Str::title($item['type']) }}</span>
</td> </td>
@ -31,19 +31,19 @@
<td class="truncate-text" style="max-width: 300px;"> <td class="truncate-text" style="max-width: 300px;">
{{ $item['content'] }} {{ $item['content'] }}
</td> </td>
<td> <td class="text-center">
<a href="{{ route('admin.pengumuman.edit', $item['id']) }}" class="btn btn-sm btn-outline-secondary"> <a href="{{ route('admin.pengumuman.edit', $item['id']) }}" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-pencil-fill"></i> <i class="bi bi-pencil-fill"></i>
</a> </a>
<button class="btn btn-sm btn-outline-danger" disabled> <button class="btn btn-sm btn-outline-danger btn-hapus" data-judul="{{ $item['title'] }}">
<i class="bi bi-trash3-fill"></i> <i class="bi bi-trash3-fill"></i>
</button> </button>
</td> </td>
</tr> </tr>
@empty @empty
<tr> <tr class="empty-row">
<td colspan="5" class="text-center py-4"> <td colspan="5" class="text-center py-4">
<p class="text-muted">Belum ada pengumuman yang dibuat.</p> <p class="text-muted mb-0">Belum ada pengumuman yang dibuat.</p>
</td> </td>
</tr> </tr>
@endforelse @endforelse
@ -52,4 +52,60 @@
</div> </div>
</div> </div>
</div> </div>
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
$(document).on('click', '.btn-hapus', function() {
const judul = $(this).data('judul');
const row = $(this).closest('tr');
modernSwal.fire({
title: 'Hapus Pengumuman?',
text: `Apakah Anda yakin ingin menghapus pengumuman "${judul}"?`,
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Ya, Hapus!',
cancelButtonText: 'Batal',
confirmButtonColor: '#dc3545',
cancelButtonColor: '#6c757d'
}).then((result) => {
if (result.isConfirmed) {
modernSwal.fire({
title: 'Menghapus...',
timer: 800,
didOpen: () => Swal.showLoading()
}).then(() => {
Toast.fire({
icon: 'success',
title: 'Berhasil',
text: 'Pengumuman telah dihapus.'
});
row.fadeOut('slow', function() {
$(this).remove();
let count = 0;
$('tbody tr').not('.empty-row').each(function(index) {
$(this).find('.row-number').text(index + 1);
count++;
});
if(count === 0) {
$('tbody').append(`
<tr class="empty-row">
<td colspan="5" class="text-center py-4">
<p class="text-muted mb-0">Belum ada pengumuman yang dibuat.</p>
</td>
</tr>
`);
}
});
});
}
});
});
});
</script>
@endpush
</x-app-layout> </x-app-layout>

View File

@ -17,7 +17,7 @@
@if ($role == 'siswa') @if ($role == 'siswa')
Masukan NISN dan kata sandi Anda. Masukan NISN dan kata sandi Anda.
@else @else
Masukan NIP dan kata sandi Anda. Masukan NIP/NIK dan kata sandi Anda.
@endif @endif
</p> </p>
</div> </div>
@ -31,7 +31,7 @@
</div> </div>
@else @else
<div class="mb-3"> <div class="mb-3">
<label for="nip" class="form-label">Nomor Induk Pegawai (NIP)</label> <label for="nip" class="form-label">NIP/NIK</label>
<input id="nip" class="form-control" type="text" name="nip" required autofocus /> <input id="nip" class="form-control" type="text" name="nip" required autofocus />
<x-input-error :messages="$errors->get('nip')" class="mt-2" /> <x-input-error :messages="$errors->get('nip')" class="mt-2" />
</div> </div>
@ -52,7 +52,7 @@
</div> </div>
{{-- Link href untuk ke Register --}} {{-- Link href untuk ke Register --}}
<p class="mt-4 text-center text-muted small"> {{-- <p class="mt-4 text-center text-muted small">
@if ($role == 'siswa') @if ($role == 'siswa')
Belum punya akun? Belum punya akun?
<a href="{{ route('register', ['role' => 'siswa']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Siswa</a> <a href="{{ route('register', ['role' => 'siswa']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Siswa</a>
@ -60,7 +60,7 @@
Belum punya akun? Belum punya akun?
<a href="{{ route('register', ['role' => 'guru']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Guru</a> <a href="{{ route('register', ['role' => 'guru']) }}" class="fw-semibold text-decoration-none">Daftar sebagai Guru</a>
@endif @endif
</p> </p> --}}
<p class="mt-3 text-center text-muted small"> <p class="mt-3 text-center text-muted small">
Kembali ke <a href="/" class="fw-semibold text-decoration-none">halaman utama</a>. Kembali ke <a href="/" class="fw-semibold text-decoration-none">halaman utama</a>.

View File

@ -14,33 +14,53 @@
<h1 class="h2 fw-semibold mb-5 text-center">Form Peminjaman Offline</h1> <h1 class="h2 fw-semibold mb-5 text-center">Form Peminjaman Offline</h1>
{{-- Informasi Peminjam --}} {{-- Informasi Peminjam --}}
<div class="mb-5"> <div class="card-body p-4">
<div class="card border-0 shadow-sm"> <div class="row g-3">
<div class="card-header bg-white py-3 d-flex justify-content-between align-items-center"> {{-- Nama Lengkap (Muncul untuk semua role) --}}
<h5 class="fw-bold m-0">Informasi Peminjam</h5> <div class="col-md-6">
<a href="{{ route('profile.edit') }}" class="btn btn-sm btn-outline-secondary ">Edit <label class="form-label text-muted small">Nama Lengkap</label>
Profil</a> <p class="fw-semibold">{{ $user['nama_lengkap'] ?? $user->name ?? '-' }}</p>
</div> </div>
<div class="card-body p-4">
<div class="row g-3"> {{-- KONDISI UNTUK GURU --}}
<div class="col-md-6"> @if(isset($user['role']) && strtolower($user['role']) == 'guru' || isset($user->role) &&
<label class="form-label text-muted small">Nama Lengkap</label> strtolower($user->role) == 'guru')
<p class="fw-semibold">{{ $user['nama_lengkap'] }}</p> <div class="col-md-6">
</div> <label class="form-label text-muted small">NIP/NIK</label>
<div class="col-md-6"> <p class="fw-semibold">{{ $user['nip'] ?? $user->nip ?? '-' }}</p>
<label class="form-label text-muted small">Nomor Handphone</label>
<p class="fw-semibold">{{ $user['nomor_hp'] }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Kelas</label>
<p class="fw-semibold">{{ $user['kelas'] }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Golongan</label>
<p class="fw-semibold">{{ $user['golongan'] }}</p>
</div>
</div>
</div> </div>
<div class="col-md-6">
<label class="form-label text-muted small">Email</label>
<p class="fw-semibold text-break">{{ $user['email'] ?? $user->email ?? '-' }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Nomor Handphone</label>
<p class="fw-semibold">{{ $user['nomor_hp'] ?? $user->nomor_hp ?? '-' }}</p>
</div>
{{-- KONDISI UNTUK SISWA --}}
@else
<div class="col-md-6">
<label class="form-label text-muted small">NISN</label>
<p class="fw-semibold">{{ $user['nisn'] ?? $user->nisn ?? '-' }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Email</label>
<p class="fw-semibold text-break">{{ $user['email'] ?? $user->email ?? '-' }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Nomor Handphone</label>
<p class="fw-semibold">{{ $user['nomor_hp'] ?? $user->nomor_hp ?? '-' }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Kelas</label>
<p class="fw-semibold">{{ $user['kelas'] ?? $user->kelas ?? '-' }}</p>
</div>
<div class="col-md-6">
<label class="form-label text-muted small">Golongan</label>
<p class="fw-semibold">{{ $user['golongan'] ?? $user->golongan ?? '-' }}</p>
</div>
@endif
</div> </div>
</div> </div>
@ -54,7 +74,7 @@
<div class="mb-5"> <div class="mb-5">
<div class="d-flex justify-content-between align-items-center border-bottom pb-2 mb-3"> <div class="d-flex justify-content-between align-items-center border-bottom pb-2 mb-3">
<h5 class="fw-bold m-0">Buku yang Dipinjam</h5> <h5 class="fw-bold m-0">Buku yang Dipinjam</h5>
<button type="button" class="btn btn-sm btn-primary " data-bs-toggle="modal" <button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal"
data-bs-target="#pilihBukuModal" id="btnTambahBuku"> data-bs-target="#pilihBukuModal" id="btnTambahBuku">
<i class="bi bi-plus-circle me-1"></i>Tambah Buku <i class="bi bi-plus-circle me-1"></i>Tambah Buku
</button> </button>
@ -158,56 +178,55 @@ class="rounded me-3 form-book-cover">
</div> </div>
</div> </div>
<!-- Daftar Buku -->
<div id="daftarBukuModal" class="row g-3"> <div id="daftarBukuModal" class="row g-3">
@foreach ($semuaBuku as $bukuItem) @foreach ($semuaBuku as $bukuItem)
@if ($bukuItem['status'] == 'Tersedia' || $bukuItem['id'] == $buku['id']) @if ($bukuItem['status'] == 'Tersedia' || $bukuItem['id'] == $buku['id'])
<div class="col-12 book-option" data-book-id="{{ $bukuItem['id'] }}" <div class="col-12 book-option" data-book-id="{{ $bukuItem['id'] }}"
data-book-title="{{ strtolower($bukuItem['judul']) }}" data-book-title="{{ strtolower($bukuItem['judul']) }}"
data-book-author="{{ strtolower($bukuItem['penulis']) }}"> data-book-author="{{ strtolower($bukuItem['penulis']) }}">
<div class="card book-card h-100 border-0 shadow-sm hover-shadow transition" <div class="card book-card h-100 border-0 shadow-sm hover-shadow transition"
onclick="toggleBookSelection({{ $bukuItem['id'] }})"> onclick="toggleBookSelection({{ $bukuItem['id'] }})">
<div class="card-body p-3"> <div class="card-body p-3">
<div class="d-flex align-items-start"> <div class="d-flex align-items-start">
<img src="{{ asset($bukuItem['cover']) }}" alt="Cover" <img src="{{ asset($bukuItem['cover']) }}" alt="Cover"
class="rounded me-3 form-book-cover" class="rounded me-3 form-book-cover"
style="width: 60px; height: 80px; object-fit: cover;"> style="width: 60px; height: 80px; object-fit: cover;">
<!-- Detail Buku --> <div class="flex-grow-1">
<div class="flex-grow-1"> <h6 class="fw-bold mb-1">{{ $bukuItem['judul'] }}</h6>
<h6 class="fw-bold mb-1">{{ $bukuItem['judul'] }}</h6> <p class="text-muted small mb-1">{{ $bukuItem['penulis'] }}</p>
<p class="text-muted small mb-1">{{ $bukuItem['penulis'] }}</p> <div class="d-flex align-items-center flex-wrap gap-2">
<div class="d-flex align-items-center flex-wrap gap-2"> <span class="badge bg-info">{{ $bukuItem['kategori'] }}</span>
<span class="badge bg-info">{{ $bukuItem['kategori'] }}</span> <span class="badge bg-success"><i
<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i>Tersedia</span>
class="bi bi-check-circle me-1"></i>Tersedia</span> @if ($bukuItem['id'] == $buku['id'])
@if ($bukuItem['id'] == $buku['id']) <span class="badge bg-primary"><i class="bi bi-star-fill me-1"></i>Buku
<span class="badge bg-primary"><i Utama</span>
class="bi bi-star-fill me-1"></i>Buku Utama</span> @endif
@endif
</div>
</div>
<div class="form-check ms-2">
<input class="form-check-input book-checkbox" type="checkbox"
value="{{ $bukuItem['id'] }}" id="book{{ $bukuItem['id'] }}"
@if ($bukuItem['id'] == $buku['id']) checked disabled @endif
onclick="event.stopPropagation()">
</div>
</div> </div>
</div> </div>
{{-- PERBAIKAN: Checkbox tag dirapikan agar @if nya satu baris --}}
<div class="form-check ms-2">
<input class="form-check-input book-checkbox" type="checkbox"
value="{{ $bukuItem['id'] }}" id="book{{ $bukuItem['id'] }}"
@if($bukuItem['id']==$buku['id']) checked disabled @endif
onclick="event.stopPropagation()">
</div>
</div> </div>
</div> </div>
@endif </div>
</div>
@endif
@endforeach @endforeach
</div> </div>
</div> </div>
<!-- Counter Buku Terpilih -->
<div class="p-3 bg-light"> <div class="p-3 bg-light">
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<span class="fw-semibold"> <span class="fw-semibold">
@ -220,13 +239,11 @@ class="bi bi-star-fill me-1"></i>Buku Utama</span>
</div> </div>
</div> </div>
<!-- Footer -->
<div class="modal-footer bg-light"> <div class="modal-footer bg-light">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal"> <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle me-1"></i> Batal <i class="bi bi-x-circle me-1"></i> Batal
</button> </button>
<button type="button" class="btn btn-primary" id="konfirmasiBuku" <button type="button" class="btn btn-primary" id="konfirmasiBuku" onclick="konfirmasiPilihanBuku()">
onclick="konfirmasiPilihanBuku()">
<i class="bi bi-check2-circle me-1"></i> Konfirmasi Pilihan <i class="bi bi-check2-circle me-1"></i> Konfirmasi Pilihan
</button> </button>
</div> </div>
@ -323,4 +340,4 @@ class="bi bi-star-fill me-1"></i>Buku Utama</span>
}); });
</script> </script>
</x-app-layout> </x-app-layout>

View File

@ -1,4 +1,4 @@
@section('page-title', 'Profile') @section('page-title', 'Profil')
<x-app-layout> <x-app-layout>
<div class="d-flex align-items-center mb-4"> <div class="d-flex align-items-center mb-4">
<a href="{{ route('profile.index') }}" class="btn btn-outline-secondary me-3"> <a href="{{ route('profile.index') }}" class="btn btn-outline-secondary me-3">

View File

@ -3,244 +3,253 @@
<div class="row g-3 g-md-4 min-vh-100 pb-4"> <div class="row g-3 g-md-4 min-vh-100 pb-4">
{{-- =================================================================== --}}
{{-- TAMPILAN PROFIL UNTUK PENJAGA PERPUSTAKAAN --}}
{{-- =================================================================== --}}
@if (Auth::user()->role == 'penjaga perpus') @if (Auth::user()->role == 'penjaga perpus')
<div class="row g-3 g-md-4 h-100">
<div class="row g-3 g-md-4 h-100"> <div class="col-lg-8 d-flex flex-column">
{{-- Kolom Kiri: Info & Statistik Global --}} <div class="card border-0 mb-3 mb-md-4">
<div class="col-lg-8 d-flex flex-column"> <div
{{-- Info Petugas --}} class="card-body p-3 p-md-4 d-flex flex-column flex-sm-row align-items-center text-center text-sm-start">
<div class="card border-0 mb-3 mb-md-4"> <img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true"
<div alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-sm-0">
class="card-body p-3 p-md-4 d-flex flex-column flex-sm-row align-items-center text-center text-sm-start"> <div class="ms-sm-4 mb-3 mb-sm-0">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true" <h4 class="fw-bold mb-1">{{ $user->name }}</h4>
alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-sm-0"> <span class="badge rounded-pill bg-success-subtle text-success-emphasis">{{
<div class="ms-sm-4"> Str::title($user->role) }}</span>
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
<span
class="badge rounded-pill bg-success-subtle text-success-emphasis">{{ Str::title($user->role) }}</span>
</div>
</div> </div>
</div> <div class="ms-sm-auto">
{{-- Statistik Perpustakaan --}}
<div class="mb-3 mb-md-4 flex-grow-1">
<h5 class="fw-bold mb-3">Statistik Perpustakaan</h5>
<div class="row g-3">
@foreach ($statistik as $stat)
<div class="col-sm-6 col-lg-3">
<div class="card border-0 h-100">
<div class="card-body p-3 p-md-4 text-center">
<div class="icon-circle bg-{{ $stat['color'] }}-light mx-auto mb-3"
style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 15px;">
<i class="bi {{ $stat['icon'] }} fs-2 text-{{ $stat['color'] }}"></i>
</div>
<h3 class="fw-bold mb-2">{{ $stat['value'] }}</h3>
<p class="text-muted mb-0 small">{{ $stat['label'] }}</p>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
{{-- Kolom Kanan: Pintasan & Aktivitas --}}
<div class="col-lg-4 d-flex flex-column">
{{-- Pintasan Manajemen --}}
<div class="card border-0 mb-3 mb-md-4 flex-grow-1">
<div class="card-body p-3 p-md-4 d-flex flex-column h-100">
<h5 class="fw-bold mb-4">Pintasan Manajemen</h5>
<div class="d-grid gap-3 flex-grow-1">
<a href="{{ route('admin.buku.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-book-fill me-3 fs-4"></i>
<span>Kelola Buku</span>
</a>
<a href="{{ route('admin.pengguna.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-people-fill me-3 fs-4"></i>
<span>Kelola Pengguna</span>
</a>
<a href="{{ route('admin.pengumuman.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-megaphone-fill me-3 fs-4"></i>
<span>Kelola Pengumuman</span>
</a>
</div>
</div>
</div>
{{-- Keamanan Akun --}}
<div class="card border-0">
<div class="card-body p-3 p-md-4">
<h5 class="fw-bold mb-3">Keamanan Akun</h5>
<p class="small text-muted mb-3">Ubah password Anda secara berkala untuk menjaga keamanan
akun.</p>
<a href="{{ route('profile.edit') }}" <a href="{{ route('profile.edit') }}"
class="btn btn-outline-secondary rounded-pill w-100 py-2"> class="btn btn-outline-primary rounded-pill w-100 w-sm-auto">
<i class="bi bi-shield-lock me-2"></i>Ubah Password
</a>
</div>
</div>
</div>
</div>
@elseif (Auth::user()->role == 'guru')
{{-- =================================================================== --}}
{{-- TAMPILAN PROFIL UNTUK GURU --}}
{{-- =================================================================== --}}
<div class="row g-3 g-md-4 h-100">
{{-- Kolom Kiri: Info & Ringkasan Laporan --}}
<div class="col-lg-8 d-flex flex-column">
{{-- Info Guru --}}
<div class="card border-0 mb-3 mb-md-4">
<div
class="card-body p-3 p-md-4 d-flex flex-column flex-md-row align-items-center text-center text-md-start">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=198754&color=fff&size=80&rounded=true"
alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-md-0">
<div class="ms-md-4 mb-3 mb-md-0">
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
<span
class="badge rounded-pill bg-success-subtle text-success-emphasis">{{ Str::title($user->role) }}</span>
</div>
<a href="{{ route('profile.edit') }}"
class="btn btn-outline-primary rounded-pill w-100 w-md-auto ms-md-auto">
<i class="bi bi-pencil-square me-2"></i>Edit Profil <i class="bi bi-pencil-square me-2"></i>Edit Profil
</a> </a>
</div> </div>
</div> </div>
{{-- Ringkasan Laporan Minat Baca --}}
<div class="card border-0 flex-grow-1">
<div class="card-body p-3 p-md-4 d-flex flex-column h-100">
<div
class="d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center mb-4 gap-2">
<h5 class="fw-bold mb-0">Ringkasan Laporan Minat Baca</h5>
<a href="{{ route('guru.laporan.index') }}"
class="btn btn-sm btn-outline-primary rounded-pill w-100 w-sm-auto">
Lihat Laporan Lengkap
</a>
</div>
<div class="row flex-grow-1">
<div class="col-md-6 mb-3 mb-md-0">
<h6 class="small text-muted mb-3 text-uppercase fw-semibold">Buku Terpopuler</h6>
<ul class="list-group list-group-flush laporan-list">
@foreach ($laporan['buku_terpopuler'] as $buku)
<li
class="list-group-item px-0 py-3 d-flex justify-content-between align-items-center">
<span class="text-truncate me-2">{{ $buku['judul'] }}</span>
<span
class="badge bg-primary rounded-pill">{{ $buku['total_pembaca'] }}</span>
</li>
@endforeach
</ul>
</div>
<div class="col-md-6">
<h6 class="small text-muted mb-3 text-uppercase fw-semibold">Kategori Terpopuler
</h6>
<ul class="list-group list-group-flush laporan-list">
@foreach ($laporan['kategori_populer'] as $kategori)
<li
class="list-group-item px-0 py-3 d-flex justify-content-between align-items-center">
<span class="text-truncate me-2">{{ $kategori['nama'] }}</span>
<span
class="badge bg-success rounded-pill">{{ $kategori['total_pembaca'] }}</span>
</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
</div> </div>
{{-- Kolom Kanan: Aktivitas Personal Guru --}} <div class="mb-3 mb-md-4 flex-grow-1">
<div class="col-lg-4"> <h5 class="fw-bold mb-3">Statistik Perpustakaan</h5>
@include('profile.partials.personal-activities', [ <div class="row g-3">
'bukuOffline' => $bukuOffline, @foreach ($statistik as $stat)
'bukuOnline' => $bukuOnline, <div class="col-sm-6 col-lg-3">
]) <div class="card border-0 h-100">
</div> <div class="card-body p-3 p-md-4 text-center">
</div> <div class="icon-circle bg-{{ $stat['color'] }}-light mx-auto mb-3"
@else style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 15px;">
{{-- =================================================================== --}} <i class="bi {{ $stat['icon'] }} fs-2 text-{{ $stat['color'] }}"></i>
{{-- TAMPILAN PROFIL UNTUK SISWA (DEFAULT) --}}
{{-- =================================================================== --}}
<div class="row g-3 g-md-4 h-100">
{{-- Kolom Kiri: Info & Statistik Siswa --}}
<div class="col-lg-8 d-flex flex-column">
{{-- Info Siswa --}}
<div class="card border-0 mb-3 mb-md-4">
<div class="card-body p-3 p-md-4">
<div class="d-flex flex-column flex-md-row align-items-center text-center text-md-start">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true"
alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-md-0">
<div class="ms-md-4 mb-3 mb-md-0">
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
<span
class="badge rounded-pill bg-primary-subtle text-primary-emphasis">{{ Str::title($user->role) }}</span>
</div>
<a href="{{ route('profile.edit') }}"
class="btn btn-outline-primary rounded-pill ms-md-auto">
<i class="bi bi-pencil-square me-2"></i>Edit Profil
</a>
</div>
<hr class="my-3 my-md-4">
<h5 class="fw-bold mb-3">Informasi Personal</h5>
<div class="row g-3">
<div class="col-sm-6">
<small class="text-muted d-block mb-1">NISN</small>
<p class="fw-semibold mb-0">{{ $user->nisn ?? 'N/A' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Email</small>
<p class="fw-semibold mb-0 text-break">{{ $user->email }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Nomor HP</small>
<p class="fw-semibold mb-0">{{ $user->nomor_hp ?? 'N/A' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Kelas</small>
<p class="fw-semibold mb-0">{{ $user->kelas ?? 'N/A' }}</p>
</div>
</div>
</div>
</div>
{{-- Statistik Personal Siswa --}}
<div class="mb-3 mb-md-4 flex-grow-1">
<h5 class="fw-bold mb-3">Statistik Saya</h5>
<div class="row g-3">
@foreach ($statistik as $stat)
<div class="col-sm-6 col-lg-3">
<div class="card border-0 h-100">
<div class="card-body p-3 p-md-4 text-center">
<div class="icon-circle bg-{{ $stat['color'] }}-light mx-auto mb-3"
style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 15px;">
<i class="bi {{ $stat['icon'] }} fs-2 text-{{ $stat['color'] }}"></i>
</div>
<h3 class="fw-bold mb-2">{{ $stat['value'] }}</h3>
<p class="text-muted mb-0 small">{{ $stat['label'] }}</p>
</div>
</div> </div>
<h3 class="fw-bold mb-2">{{ $stat['value'] }}</h3>
<p class="text-muted mb-0 small">{{ $stat['label'] }}</p>
</div> </div>
@endforeach </div>
</div>
@endforeach
</div>
</div>
</div>
<div class="col-lg-4 d-flex flex-column">
<div class="card border-0 mb-3 mb-md-4 flex-grow-1">
<div class="card-body p-3 p-md-4 d-flex flex-column h-100">
<h5 class="fw-bold mb-4">Pintasan Manajemen</h5>
<div class="d-grid gap-3 flex-grow-1">
<a href="{{ route('admin.buku.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-book-fill me-3 fs-4"></i>
<span>Kelola Buku</span>
</a>
<a href="{{ route('admin.pengguna.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-people-fill me-3 fs-4"></i>
<span>Kelola Pengguna</span>
</a>
<a href="{{ route('admin.pengumuman.index') }}"
class="btn btn-light text-start py-3 d-flex align-items-center">
<i class="bi bi-megaphone-fill me-3 fs-4"></i>
<span>Kelola Pengumuman</span>
</a>
</div> </div>
</div> </div>
</div> </div>
{{-- Kolom Kanan: Aktivitas Personal Siswa --}} <div class="card border-0">
<div class="col-lg-4"> <div class="card-body p-3 p-md-4">
@include('profile.partials.personal-activities', [ <h5 class="fw-bold mb-3">Keamanan Akun</h5>
'bukuOffline' => $bukuOffline, <p class="small text-muted mb-3">Ubah password Anda secara berkala untuk menjaga keamanan akun.
'bukuOnline' => $bukuOnline, </p>
]) <a href="{{ route('profile.edit') }}" class="btn btn-outline-secondary rounded-pill w-100 py-2">
<i class="bi bi-shield-lock me-2"></i>Ubah Password
</a>
</div>
</div> </div>
</div> </div>
</div>
@elseif (Auth::user()->role == 'guru')
<div class="row g-3 g-md-4 h-100">
<div class="col-lg-8 d-flex flex-column">
<div class="card border-0 mb-3 mb-md-4">
<div class="card-body p-3 p-md-4">
<div class="d-flex flex-column flex-sm-row align-items-center text-center text-sm-start">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=198754&color=fff&size=80&rounded=true"
alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-sm-0">
<div class="ms-sm-4 mb-3 mb-sm-0">
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
<span class="badge rounded-pill bg-success-subtle text-success-emphasis">{{
Str::title($user->role) }}</span>
</div>
<div class="ms-sm-auto">
<a href="{{ route('profile.edit') }}"
class="btn btn-outline-primary rounded-pill ms-sm-auto w-100 w-sm-auto">
<i class="bi bi-pencil-square me-2"></i>Edit Profil
</a>
</div>
</div>
<hr class="my-3 my-md-4">
<h5 class="fw-bold mb-3">Informasi Personal</h5>
<div class="row g-3">
<div class="col-sm-6">
<small class="text-muted d-block mb-1">NIP/NIK</small>
<p class="fw-semibold mb-0">{{ $user->nip ?? $user->nisn ?? '-' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Email</small>
<p class="fw-semibold mb-0 text-break">{{ $user->email }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Nomor HP</small>
<p class="fw-semibold mb-0">{{ $user->nomor_hp ?? '-' }}</p>
</div>
</div>
</div>
</div>
<div class="card border-0 flex-grow-1">
<div class="card-body p-3 p-md-4 d-flex flex-column h-100">
<div
class="d-flex flex-column flex-sm-row justify-content-between align-items-center mb-4 gap-3">
<h5 class="fw-bold mb-0">Ringkasan Laporan Minat Baca</h5>
<div class="ms-sm-auto">
<a href="{{ route('guru.laporan.index') }}"
class="btn btn-sm btn-outline-primary rounded-pill w-100 w-sm-auto">
Lihat Laporan Lengkap
</a>
</div>
</div>
<div class="row flex-grow-1">
<div class="col-md-6 mb-3 mb-md-0">
<h6 class="small text-muted mb-3 text-uppercase fw-semibold">Buku Terpopuler</h6>
<ul class="list-group list-group-flush laporan-list">
@foreach ($laporan['buku_terpopuler'] as $buku)
<li
class="list-group-item px-0 py-3 d-flex justify-content-between align-items-center">
<span class="text-truncate me-2">{{ $buku['judul'] }}</span>
<span class="badge bg-primary rounded-pill">{{ $buku['total_pembaca'] }}</span>
</li>
@endforeach
</ul>
</div>
<div class="col-md-6">
<h6 class="small text-muted mb-3 text-uppercase fw-semibold">Kategori Terpopuler</h6>
<ul class="list-group list-group-flush laporan-list">
@foreach ($laporan['kategori_populer'] as $kategori)
<li
class="list-group-item px-0 py-3 d-flex justify-content-between align-items-center">
<span class="text-truncate me-2">{{ $kategori['nama'] }}</span>
<span class="badge bg-success rounded-pill">{{ $kategori['total_pembaca']
}}</span>
</li>
@endforeach
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
@include('profile.partials.personal-activities', [
'bukuOffline' => $bukuOffline,
'bukuOnline' => $bukuOnline,
])
</div>
</div>
@else
<div class="row g-3 g-md-4 h-100">
<div class="col-lg-8 d-flex flex-column">
<div class="card border-0 mb-3 mb-md-4">
<div class="card-body p-3 p-md-4">
<div class="d-flex flex-column flex-sm-row align-items-center text-center text-sm-start">
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true"
alt="Foto Profil" class="rounded-circle profile-avatar-lg mb-3 mb-sm-0">
<div class="ms-sm-4 mb-3 mb-sm-0">
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
<span class="badge rounded-pill bg-primary-subtle text-primary-emphasis">{{
Str::title($user->role) }}</span>
</div>
<div class="ms-sm-auto">
<a href="{{ route('profile.edit') }}"
class="btn btn-outline-primary rounded-pill ms-sm-auto w-100 w-sm-auto">
<i class="bi bi-pencil-square me-2"></i>Edit Profil
</a>
</div>
</div>
<hr class="my-3 my-md-4">
<h5 class="fw-bold mb-3">Informasi Personal</h5>
<div class="row g-3">
<div class="col-sm-6">
<small class="text-muted d-block mb-1">NISN</small>
<p class="fw-semibold mb-0">{{ $user->nisn ?? '-' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Email</small>
<p class="fw-semibold mb-0 text-break">{{ $user->email }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Nomor HP</small>
<p class="fw-semibold mb-0">{{ $user->nomor_hp ?? '-' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Kelas</small>
<p class="fw-semibold mb-0">{{ $user->kelas ?? '-' }}</p>
</div>
<div class="col-sm-6">
<small class="text-muted d-block mb-1">Golongan</small>
<p class="fw-semibold mb-0">{{ $user->golongan ?? '-' }}</p>
</div>
</div>
</div>
</div>
<div class="mb-3 mb-md-4 flex-grow-1">
<h5 class="fw-bold mb-3">Statistik Saya</h5>
<div class="row g-3">
@foreach ($statistik as $stat)
<div class="col-sm-6 col-lg-3">
<div class="card border-0 h-100">
<div class="card-body p-3 p-md-4 text-center">
<div class="icon-circle bg-{{ $stat['color'] }}-light mx-auto mb-3"
style="width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 15px;">
<i class="bi {{ $stat['icon'] }} fs-2 text-{{ $stat['color'] }}"></i>
</div>
<h3 class="fw-bold mb-2">{{ $stat['value'] }}</h3>
<p class="text-muted mb-0 small">{{ $stat['label'] }}</p>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
<div class="col-lg-4">
@include('profile.partials.personal-activities', [
'bukuOffline' => $bukuOffline,
'bukuOnline' => $bukuOnline,
])
</div>
</div>
@endif @endif
</div> </div>
</x-app-layout> </x-app-layout>

View File

@ -1,11 +1,11 @@
<section> <section>
<header> <header>
<h2 class="h5 fw-bold"> <h2 class="h5 fw-bold text-dark">
{{ __('Update Password') }} {{ __('Update Password') }}
</h2> </h2>
<p class="mt-1 text-muted small"> <p class="mt-1 text-muted small">
{{ __('Ensure your account is using a long, random password to stay secure.') }} {{ __('Pastikan akun Anda menggunakan kata sandi yang panjang dan acak untuk menjaga keamanan.') }}
</p> </p>
</header> </header>
@ -15,43 +15,89 @@
{{-- Current Password --}} {{-- Current Password --}}
<div class="mb-3"> <div class="mb-3">
<label for="update_password_current_password" class="form-label">{{ __('Current Password') }}</label> <label for="update_password_current_password" class="form-label">{{ __('Kata Sandi Saat Ini') }}</label>
<input id="update_password_current_password" name="current_password" type="password" <div class="input-group">
class="form-control @error('current_password', 'updatePassword') is-invalid @enderror" <input id="update_password_current_password" name="current_password" type="password"
autocomplete="current-password"> class="form-control @error('current_password', 'updatePassword') is-invalid @enderror"
@error('current_password', 'updatePassword') autocomplete="current-password">
<div class="invalid-feedback">{{ $message }}</div> <button class="btn btn-outline-secondary toggle-password" type="button">
@enderror <i class="bi bi-eye-slash"></i>
</button>
@error('current_password', 'updatePassword')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div> </div>
{{-- New Password --}} {{-- New Password --}}
<div class="mb-3"> <div class="mb-3">
<label for="update_password_password" class="form-label">{{ __('New Password') }}</label> <label for="update_password_password" class="form-label">{{ __('Kata Sandi Baru') }}</label>
<input id="update_password_password" name="password" type="password" <div class="input-group">
class="form-control @error('password', 'updatePassword') is-invalid @enderror" <input id="update_password_password" name="password" type="password"
autocomplete="new-password"> class="form-control @error('password', 'updatePassword') is-invalid @enderror"
@error('password', 'updatePassword') autocomplete="new-password">
<div class="invalid-feedback">{{ $message }}</div> <button class="btn btn-outline-secondary toggle-password" type="button">
@enderror <i class="bi bi-eye-slash"></i>
</button>
@error('password', 'updatePassword')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div> </div>
{{-- Confirm Password --}} {{-- Confirm Password --}}
<div class="mb-3"> <div class="mb-3">
<label for="update_password_password_confirmation" class="form-label">{{ __('Confirm Password') }}</label> <label for="update_password_password_confirmation" class="form-label">{{ __('Konfirmasi Kata Sandi') }}</label>
<input id="update_password_password_confirmation" name="password_confirmation" type="password" <div class="input-group">
class="form-control @error('password_confirmation', 'updatePassword') is-invalid @enderror" <input id="update_password_password_confirmation" name="password_confirmation" type="password"
autocomplete="new-password"> class="form-control @error('password_confirmation', 'updatePassword') is-invalid @enderror"
@error('password_confirmation', 'updatePassword') autocomplete="new-password">
<div class="invalid-feedback">{{ $message }}</div> <button class="btn btn-outline-secondary toggle-password" type="button">
@enderror <i class="bi bi-eye-slash"></i>
</button>
@error('password_confirmation', 'updatePassword')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
</div> </div>
<div class="d-flex align-items-center gap-3"> <div class="d-flex align-items-center gap-3 mt-4">
<button type="submit" class="btn btn-primary">{{ __('Save') }}</button> <button type="submit" class="btn btn-primary px-4 shadow-sm">
<i class="bi bi-save me-1"></i> {{ __('Simpan Perubahan') }}
@if (session('status') === 'password-updated') </button>
<span class="text-success fw-bold">{{ __('Saved.') }}</span>
@endif
</div> </div>
</form> </form>
</section>
<script>
document.addEventListener('DOMContentLoaded', function() {
const toggleButtons = document.querySelectorAll('.toggle-password');
toggleButtons.forEach(button => {
button.addEventListener('click', function() {
const input = this.parentElement.querySelector('input');
const icon = this.querySelector('i');
if (input.type === 'password') {
input.type = 'text';
icon.classList.remove('bi-eye-slash');
icon.classList.add('bi-eye');
} else {
input.type = 'password';
icon.classList.remove('bi-eye');
icon.classList.add('bi-eye-slash');
}
});
});
@if (session('status') === 'password-updated')
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: 'Kata sandi baru sudah berhasil diperbarui.',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true
});
@endif
});
</script>
</section>

View File

@ -60,7 +60,15 @@
<span <span
class="badge rounded-pill bg-success-subtle text-success-emphasis">Dikembalikan</span> class="badge rounded-pill bg-success-subtle text-success-emphasis">Dikembalikan</span>
@elseif($isTelat) @elseif($isTelat)
<span class="badge rounded-pill bg-danger text-white">Terlambat</span> {{-- LOGIC BADGE STATUS DI TABEL --}}
@if (Auth::user()->role == 'guru')
<span
class="badge rounded-pill bg-success-subtle text-success-emphasis">Bebas
Denda</span>
@else
<span
class="badge rounded-pill bg-danger text-white">Terlambat</span>
@endif
@else @else
<span <span
class="badge rounded-pill bg-warning-subtle text-warning-emphasis">Dipinjam</span> class="badge rounded-pill bg-warning-subtle text-warning-emphasis">Dipinjam</span>
@ -105,6 +113,8 @@ class="badge rounded-pill bg-warning-subtle text-warning-emphasis">Dipinjam</spa
<script> <script>
const riwayatOfflineData = @json($riwayatOffline); const riwayatOfflineData = @json($riwayatOffline);
const currentUserRole = "{{ Auth::user()->role }}";
$(document).ready(function() { $(document).ready(function() {
$('#riwayatOfflineTable').DataTable({ $('#riwayatOfflineTable').DataTable({
responsive: true, responsive: true,
@ -156,24 +166,47 @@ class="badge rounded-pill bg-warning-subtle text-warning-emphasis">Dipinjam</spa
const buku = transaksiItem.books.find(b => b.id == bukuId); const buku = transaksiItem.books.find(b => b.id == bukuId);
if (!buku) return; if (!buku) return;
const dendaHtml = isTelat ? ` let dendaHtml = '';
<div class="card border-0 border-start border-4 border-danger bg-danger-subtle mb-3 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="flex-shrink-0 me-3">
<i class="bi bi-exclamation-octagon-fill text-danger fs-1"></i>
</div>
<div class="text-start">
<h6 class="fw-bold text-danger mb-1">Terlambat Pengembalian!</h6>
<p class="mb-0 small text-danger-emphasis">
Anda terlambat <span class="badge bg-danger text-white">${hariTelat} Hari</span>.
Denda yang harus dibayar:
<span class="fw-bold fs-6 d-block mt-1">Rp ${denda}</span>
</p>
</div>
</div>
</div>` : '';
const keteranganHtml = buku.keterangan ? ` if (isTelat) {
if (currentUserRole === 'guru') {
// JIKA GURU: Tampilkan Label Bebas Denda (Hijau)
dendaHtml = `
<div class="card border-0 border-start border-4 border-success bg-success-subtle mb-3 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="flex-shrink-0 me-3">
<i class="bi bi-check-circle-fill text-success fs-1"></i>
</div>
<div class="text-start">
<h6 class="fw-bold text-success mb-1">Bebas Denda</h6>
<p class="mb-0 small text-success-emphasis">
Sebagai Guru, Anda dibebaskan dari denda keterlambatan buku.
</p>
</div>
</div>
</div>`;
} else {
// JIKA SISWA: Tampilkan Label Denda (Merah)
dendaHtml = `
<div class="card border-0 border-start border-4 border-danger bg-danger-subtle mb-3 shadow-sm">
<div class="card-body p-3 d-flex align-items-center">
<div class="flex-shrink-0 me-3">
<i class="bi bi-exclamation-octagon-fill text-danger fs-1"></i>
</div>
<div class="text-start">
<h6 class="fw-bold text-danger mb-1">Terlambat Pengembalian!</h6>
<p class="mb-0 small text-danger-emphasis">
Anda terlambat <span class="badge bg-danger text-white">${hariTelat} Hari</span>.
Denda yang harus dibayar:
<span class="fw-bold fs-6 d-block mt-1">Rp ${denda}</span>
</p>
</div>
</div>
</div>`;
}
}
const keteranganHtml = buku.keterangan ? `
<div class="card border-0 border-start border-4 border-warning bg-warning-subtle mb-4 shadow-sm"> <div class="card border-0 border-start border-4 border-warning bg-warning-subtle mb-4 shadow-sm">
<div class="card-body p-3 d-flex align-items-start"> <div class="card-body p-3 d-flex align-items-start">
<div class="flex-shrink-0 me-3"> <div class="flex-shrink-0 me-3">
@ -188,8 +221,8 @@ class="badge rounded-pill bg-warning-subtle text-warning-emphasis">Dipinjam</spa
</div> </div>
</div>` : ''; </div>` : '';
// RENDER HTML // RENDER HTML
modalBody.innerHTML = ` modalBody.innerHTML = `
<div class="text-center mb-4"> <div class="text-center mb-4">
<img src="{{ asset('') }}${buku.cover}" class="img-fluid rounded shadow-sm" style="max-width: 140px;"> <img src="{{ asset('') }}${buku.cover}" class="img-fluid rounded shadow-sm" style="max-width: 140px;">
</div> </div>

View File

@ -13,14 +13,14 @@
<body data-bs-spy="scroll" data-bs-target="#mainNav" data-bs-offset="56"> <body data-bs-spy="scroll" data-bs-target="#mainNav" data-bs-offset="56">
@php @php
// Dummy data untuk landing page (Hanya contoh) // Dummy data untuk landing page (Hanya contoh)
$buku_unggulan = \App\Services\DummyDataService::getAllBooks()->take(6); $buku_unggulan = \App\Services\DummyDataService::getAllBooks()->take(6);
$stats = [ $stats = [
['label' => 'Koleksi Buku', 'value' => 12500, 'icon' => 'bi-bookshelf'], ['label' => 'Koleksi Buku', 'value' => 12500, 'icon' => 'bi-bookshelf'],
['label' => 'Pengguna Aktif', 'value' => 4500, 'icon' => 'bi-person-lines-fill'], ['label' => 'Pengguna Aktif', 'value' => 4500, 'icon' => 'bi-person-lines-fill'],
['label' => 'Total Dibaca', 'value' => '900K+', 'icon' => 'bi-hand-thumbs-up-fill'], ['label' => 'Total Dibaca', 'value' => '900K+', 'icon' => 'bi-hand-thumbs-up-fill'],
['label' => 'Tahun Berdiri', 'value' => 2018, 'icon' => 'bi-clock-fill'], ['label' => 'Tahun Berdiri', 'value' => 2018, 'icon' => 'bi-clock-fill'],
]; ];
@endphp @endphp
{{-- Navbar --}} {{-- Navbar --}}
@ -85,8 +85,8 @@ class="btn btn-primary dropdown-toggle fw-semibold w-100 d-flex align-items-cent
<i class="bi bi-person-workspace text-success" style="font-size: 1.25rem;"></i> <i class="bi bi-person-workspace text-success" style="font-size: 1.25rem;"></i>
<div> <div>
<div class="fw-semibold">Guru</div> <div class="fw-semibold">Guru</div>
<small class="text-muted d-block" style="font-size: 0.75rem;">Kelola <small class="text-muted d-block" style="font-size: 0.75rem;">Pinjam, Baca &
Buku</small> Pantau Laporan</small>
</div> </div>
</a> </a>
</li> </li>
@ -149,24 +149,24 @@ class="img-fluid" style="max-width: 100%; height: auto;">
<h2 class="text-center fw-bold mb-5">Koleksi Unggulan Terbaru</h2> <h2 class="text-center fw-bold mb-5">Koleksi Unggulan Terbaru</h2>
<div class="row g-4 mb-4 justify-content-center"> <div class="row g-4 mb-4 justify-content-center">
@foreach ($buku_unggulan as $buku) @foreach ($buku_unggulan as $buku)
<div class="col-6 col-md-4 col-lg-2"> <div class="col-6 col-md-4 col-lg-2">
<div class="card h-100 border-0 shadow-sm"> <div class="card h-100 border-0 shadow-sm">
<img src="{{ asset($buku['cover']) }}" class="card-img-top" <img src="{{ asset($buku['cover']) }}" class="card-img-top"
alt="Cover {{ $buku['judul'] }}"> alt="Cover {{ $buku['judul'] }}">
<div class="card-body p-3"> <div class="card-body p-3">
<span <span class="badge bg-primary-soft text-primary small mb-2">{{ $buku['kategori']
class="badge bg-primary-soft text-primary small mb-2">{{ $buku['kategori'] }}</span> }}</span>
<h6 class="card-title fw-bold mb-1">{{ $buku['judul'] }}</h6> <h6 class="card-title fw-bold mb-1">{{ $buku['judul'] }}</h6>
<p class="card-text small text-muted mb-1">{{ $buku['penulis'] }}</p> <p class="card-text small text-muted mb-1">{{ $buku['penulis'] }}</p>
<div class="small text-warning"> <div class="small text-warning">
<i class="bi bi-star-fill"></i><i class="bi bi-star-fill"></i><i <i class="bi bi-star-fill"></i><i class="bi bi-star-fill"></i><i
class="bi bi-star-fill"></i><i class="bi bi-star-fill"></i><i class="bi bi-star-fill"></i><i class="bi bi-star-fill"></i><i
class="bi bi-star-half"></i> class="bi bi-star-half"></i>
(4.5) (4.5)
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
@endforeach @endforeach
</div> </div>
</div> </div>
@ -262,9 +262,9 @@ class="bi bi-star-half"></i>
{{-- Bagian Logo (Kolom Kanan) --}} {{-- Bagian Logo (Kolom Kanan) --}}
<div class="col-lg-6 order-lg-2 text-center"> <div class="col-lg-6 order-lg-2 text-center">
<img src="{{ asset('images/assets/logo-smp.png') }}" alt="Logo SMPN 1 Bagor" <img src="{{ asset('images/assets/logo-smp.png') }}" alt="Logo SMPN 1 Bagor" class="img-fluid"
class="img-fluid" style="max-width: 250px; height: auto;"> style="max-width: 250px; height: auto;">
</div> </div>
{{-- Bagian Teks (Kolom Kiri) --}} {{-- Bagian Teks (Kolom Kiri) --}}
<div class="col-lg-6 order-lg-1"> <div class="col-lg-6 order-lg-1">
@ -301,13 +301,13 @@ class="img-fluid" style="max-width: 250px; height: auto;">
<h2 class="text-center fw-bold mb-5 text-dark">DIGIPUS.GO Dalam Angka</h2> <h2 class="text-center fw-bold mb-5 text-dark">DIGIPUS.GO Dalam Angka</h2>
<div class="row g-4 text-center"> <div class="row g-4 text-center">
@foreach ($stats as $stat) @foreach ($stats as $stat)
<div class="col-sm-6 col-md-3"> <div class="col-sm-6 col-md-3">
<div class="p-4 bg-white shadow-sm h-100 landing-stat-card" style="border-radius: 1rem;"> <div class="p-4 bg-white shadow-sm h-100 landing-stat-card" style="border-radius: 1rem;">
<i class="bi {{ $stat['icon'] }} display-5 text-primary mb-3"></i> <i class="bi {{ $stat['icon'] }} display-5 text-primary mb-3"></i>
<h2 class="fw-bold text-dark mb-1">{{ $stat['value'] }}</h2> <h2 class="fw-bold text-dark mb-1">{{ $stat['value'] }}</h2>
<p class="text-muted fw-semibold mb-0">{{ $stat['label'] }}</p> <p class="text-muted fw-semibold mb-0">{{ $stat['label'] }}</p>
</div>
</div> </div>
</div>
@endforeach @endforeach
</div> </div>
</div> </div>
@ -358,8 +358,8 @@ class="img-fluid" style="max-width: 250px; height: auto;">
</li> </li>
<li class="mb-2"><a href="#fitur" class="text-decoration-none text-white-50">Fitur</a> <li class="mb-2"><a href="#fitur" class="text-decoration-none text-white-50">Fitur</a>
</li> </li>
<li class="mb-2"><a href="#statistik" <li class="mb-2"><a href="#statistik" class="text-decoration-none text-white-50">Statistik</a>
class="text-decoration-none text-white-50">Statistik</a></li> </li>
</ul> </ul>
</div> </div>
@ -408,4 +408,4 @@ class="text-decoration-none text-white-50">Statistik</a></li>
</script> </script>
</body> </body>
</html> </html>

View File

@ -12,10 +12,10 @@
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::middleware('guest')->group(function () { Route::middleware('guest')->group(function () {
Route::get('register', [RegisteredUserController::class, 'create']) // Route::get('register', [RegisteredUserController::class, 'create'])
->name('register'); // ->name('register');
Route::post('register', [RegisteredUserController::class, 'store']); // Route::post('register', [RegisteredUserController::class, 'store']);
Route::get('login', [AuthenticatedSessionController::class, 'create']) Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login'); ->name('login');