TKK_E3220375/resources/views/admin/siswa/index.blade.php

216 lines
14 KiB
PHP

@extends('layouts.dashboard')
@section('title', 'Smart School | Data Siswa')
@section('content')
<div class="container mx-auto px-4 py-6 relative">
<!-- Toast Notification Container -->
<div class="absolute top-4 right-4 space-y-3 z-50">
<!-- Toast for Success -->
@if (session('success'))
<div id="toast-success" class="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow-lg" role="alert">
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"/>
</svg>
<span class="sr-only">Check icon</span>
</div>
<div class="ml-3 text-sm font-normal">{{ session('success') }}</div>
<button type="button" class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex items-center justify-center h-8 w-8" data-dismiss-target="#toast-success" aria-label="Close">
<span class="sr-only">Close</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
</button>
</div>
@endif
<!-- Toast for General Errors -->
@if (session('error'))
<div id="toast-danger" class="flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow-lg" role="alert">
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-red-500 bg-red-100 rounded-lg">
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"><path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM10 15a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-4a1 1 0 0 1-2 0V6a1 1 0 0 1 2 0v5Z"/></svg>
<span class="sr-only">Error icon</span>
</div>
<div class="ml-3 text-sm font-normal">{{ session('error') }}</div>
<button type="button" class="ml-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex items-center justify-center h-8 w-8" data-dismiss-target="#toast-danger" aria-label="Close">
<span class="sr-only">Close</span>
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/></svg>
</button>
</div>
@endif
</div>
<div class="bg-white rounded-2xl shadow-xl overflow-hidden">
<!-- Header Card -->
<div class="bg-gradient-to-br from-indigo-600 to-purple-600 px-8 py-6">
<div class="flex flex-col md:flex-row md:items-center md:justify-between">
<div class="mb-4 md:mb-0">
<h1 class="text-2xl font-bold text-white flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" /></svg>
Data Siswa
</h1>
<p class="text-indigo-100 mt-1">Total {{ $siswa->total() }} siswa terdaftar</p>
</div>
<div>
<a href="{{ route('admin.siswa.create') }}" class="flex items-center px-4 py-2 bg-white text-indigo-600 rounded-lg shadow hover:bg-gray-50 transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" /></svg>
Tambah Siswa
</a>
</div>
</div>
</div>
<!-- Content Section -->
<div class="p-6">
<!-- Search and Filter -->
<div class="mb-6 flex flex-col md:flex-row md:items-center justify-between gap-4">
{{-- Form untuk Search, Kelas, dan Jurusan --}}
<form action="{{ route('admin.siswa.index') }}" method="GET" class="flex flex-col md:flex-row md:items-center gap-4 w-full">
<div class="relative w-full md:w-64">
<input type="text" name="search" placeholder="Cari siswa..." value="{{ request('search') }}"
class="w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:border-indigo-500 focus:ring focus:ring-indigo-200 transition">
<div class="absolute left-3 top-2.5 text-gray-400">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
</div>
</div>
<div class="flex items-center gap-2">
<select name="kelas" class="rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 transition">
<option value="">Semua Kelas</option>
@foreach($kelas as $item)
<option value="{{ $item->id }}" {{ request('kelas') == $item->id ? 'selected' : '' }}>
{{ $item->nama_kelas }}
</option>
@endforeach
</select>
<select name="jurusan" class="rounded-lg border-gray-300 shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 transition">
<option value="">Semua Jurusan</option>
@foreach($jurusan as $item)
<option value="{{ $item->id }}" {{ request('jurusan') == $item->id ? 'selected' : '' }}>
{{ $item->nama_jurusan }}
</option>
@endforeach
</select>
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition">Filter</button>
@if(request('search') || request('kelas') || request('jurusan'))
<a href="{{ route('admin.siswa.index') }}" class="px-3 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition">
Reset
</a>
@endif
</div>
</form>
</div>
<!-- Students Table -->
<div class="overflow-x-auto rounded-lg border border-gray-200 shadow-sm">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Foto</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nama Siswa</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">NISN</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Kelas/Jurusan</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Kontak</th>
<th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($siswa as $item)
<tr class="hover:bg-gray-50 transition">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex-shrink-0 h-10 w-10 rounded-full overflow-hidden border border-gray-200">
{{-- Mengambil foto pertama dari relasi 'fotos' --}}
@if($item->fotos && $item->fotos->isNotEmpty())
<img class="h-full w-full object-cover" src="{{ asset('storage/' . $item->fotos->first()->path) }}" alt="Foto {{ $item->nama_siswa }}">
@else
<div class="bg-gray-200 h-full w-full flex items-center justify-center text-gray-400">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
</div>
@endif
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">{{ $item->nama_siswa }}</div>
<div class="text-sm text-gray-500">{{ $item->jenis_kelamin == 'L' ? 'Laki-laki' : 'Perempuan' }} {{ \Carbon\Carbon::parse($item->tanggal_lahir)->age }} tahun</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ $item->nisn }}</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">{{ $item->kelas->nama_kelas ?? '-' }}</div>
<div class="text-sm text-gray-500">{{ $item->jurusan->nama_jurusan ?? '-' }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<div>{{ $item->email }}</div>
<div>{{ $item->no_hp }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div class="flex justify-end space-x-2">
<a href="{{ route('admin.siswa.edit', $item->id) }}" class="text-indigo-600 hover:text-indigo-900 p-1 rounded hover:bg-indigo-50 transition" title="Edit">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" /></svg>
</a>
<form id="delete-form-{{ $item->id }}" action="{{ route('admin.siswa.destroy', $item->id) }}" method="POST" class="inline">
@csrf
@method('DELETE')
<button type="button" onclick="confirmDelete('{{ $item->id }}', '{{ $item->nama_siswa }}')" class="text-red-600 hover:text-red-900 p-1 rounded hover:bg-red-50 transition" title="Hapus">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
</button>
</form>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-4 text-center text-gray-500">Tidak ada data siswa ditemukan.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="p-6">
{{ $siswa->appends(request()->query())->links() }}
</div>
</div>
</div>
</div>
<!-- Include SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
// Hilangkan toast setelah 5 detik
window.setTimeout(function() {
const toastElements = document.querySelectorAll('[id^="toast-"]');
toastElements.forEach(function(toast) {
const closeButton = toast.querySelector('[data-dismiss-target]');
if (closeButton) {
closeButton.click();
}
});
}, 5000);
// Konfirmasi hapus dengan SweetAlert2
function confirmDelete(id, name) {
Swal.fire({
title: 'Hapus Siswa?',
html: `Anda akan menghapus siswa: <strong>${name}</strong><br>Data yang dihapus tidak dapat dikembalikan!`,
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: 'Ya, Hapus!',
cancelButtonText: 'Batal'
}).then((result) => {
if (result.isConfirmed) {
document.getElementById(`delete-form-${id}`).submit();
}
});
}
</script>
@endsection