Files
database-kesiswaan/resources/views/students/show.blade.php
T
2026-04-12 06:24:30 +00:00

265 lines
20 KiB
PHP

<x-master-page title="Detail Siswa" description="Ringkasan lengkap data siswa yang tersimpan di sistem.">
@php
$isAdmin = auth()->user()?->isAdmin() ?? false;
@endphp
<div class="mb-6 rounded-3xl border border-slate-200 bg-white p-6 shadow-sm shadow-slate-200/50">
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
<div>
<h3 class="text-lg font-semibold text-slate-900">Kelengkapan Dokumen Wajib</h3>
<p class="mt-1 text-sm text-slate-500">Ringkasan upload dan verifikasi dokumen wajib siswa.</p>
</div>
<div class="grid grid-cols-2 gap-4 text-right">
<div>
<div class="text-3xl font-bold text-slate-900">{{ $requiredDocumentSummary['percentage'] }}%</div>
<div class="text-sm {{ $requiredDocumentSummary['missing'] === 0 ? 'text-emerald-600' : 'text-amber-600' }}">
{{ $requiredDocumentSummary['missing'] === 0 ? 'Upload lengkap' : 'Kurang ' . $requiredDocumentSummary['missing'] . ' dokumen' }}
</div>
</div>
<div>
<div class="text-3xl font-bold text-slate-900">{{ $requiredDocumentSummary['verification_percentage'] }}%</div>
<div class="text-sm {{ $requiredDocumentSummary['unverified'] === 0 && $requiredDocumentSummary['missing'] === 0 ? 'text-emerald-600' : 'text-sky-600' }}">
{{ $requiredDocumentSummary['unverified'] === 0 && $requiredDocumentSummary['missing'] === 0 ? 'Terverifikasi penuh' : $requiredDocumentSummary['unverified'] . ' belum valid' }}
</div>
</div>
</div>
</div>
<div class="mt-4 space-y-4">
<div>
<div class="mb-2 flex items-center justify-between text-xs font-semibold uppercase tracking-[0.16em] text-slate-400">
<span>Upload Dokumen Wajib</span>
<span>{{ $requiredDocumentSummary['uploaded'] }}/{{ $requiredDocumentSummary['total'] }}</span>
</div>
<div class="h-3 overflow-hidden rounded-full bg-slate-200">
<div class="h-full rounded-full {{ $requiredDocumentSummary['missing'] === 0 ? 'bg-emerald-500' : 'bg-amber-500' }}" style="width: {{ $requiredDocumentSummary['percentage'] }}%"></div>
</div>
</div>
<div>
<div class="mb-2 flex items-center justify-between text-xs font-semibold uppercase tracking-[0.16em] text-slate-400">
<span>Verifikasi Dokumen Wajib</span>
<span>{{ $requiredDocumentSummary['verified'] }}/{{ $requiredDocumentSummary['total'] }}</span>
</div>
<div class="h-3 overflow-hidden rounded-full bg-slate-200">
<div class="h-full rounded-full {{ $requiredDocumentSummary['unverified'] === 0 && $requiredDocumentSummary['missing'] === 0 ? 'bg-sky-500' : 'bg-slate-500' }}" style="width: {{ $requiredDocumentSummary['verification_percentage'] }}%"></div>
</div>
</div>
</div>
@if ($requiredDocumentSummary['missing_items']->isNotEmpty() || $requiredDocumentSummary['unverified_items']->isNotEmpty())
<div class="mt-4 flex flex-wrap gap-2">
@foreach ($requiredDocumentSummary['missing_items'] as $missingDocument)
<span class="rounded-full bg-rose-100 px-3 py-1 text-xs font-semibold text-rose-700">Belum upload: {{ $missingDocument }}</span>
@endforeach
@foreach ($requiredDocumentSummary['unverified_items'] as $unverifiedDocument)
<span class="rounded-full bg-sky-100 px-3 py-1 text-xs font-semibold text-sky-700">Belum valid: {{ $unverifiedDocument }}</span>
@endforeach
</div>
@endif
</div>
<div class="grid grid-cols-1 gap-6 xl:grid-cols-3">
<x-master-card title="Identitas Utama" subtitle="Informasi inti siswa.">
<div class="space-y-4 text-sm text-slate-600">
<div><span class="font-semibold text-slate-800">Nama:</span> {{ $student->full_name }}</div>
<div><span class="font-semibold text-slate-800">NIS:</span> {{ $student->student_number ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">NISN:</span> {{ $student->nisn ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Jenis Kelamin:</span> {{ $student->gender === 'L' ? 'Laki-laki' : 'Perempuan' }}</div>
<div><span class="font-semibold text-slate-800">TTL:</span> {{ $student->place_of_birth ?: '-' }}, {{ $student->date_of_birth?->format('d-m-Y') ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Agama:</span> {{ $student->religion ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Kewarganegaraan:</span> {{ $student->nationality ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Status:</span> {{ ucfirst($student->status) }}</div>
</div>
</x-master-card>
<x-master-card title="Akademik" subtitle="Relasi akademik siswa.">
<div class="space-y-4 text-sm text-slate-600">
<div><span class="font-semibold text-slate-800">Tahun Angkatan:</span> {{ $student->academicYear?->name ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Program Keahlian:</span> {{ $student->department?->name ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Kelas:</span> {{ $student->classRoom?->name ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Tanggal Masuk:</span> {{ $student->entry_date?->format('d-m-Y') ?: '-' }}</div>
</div>
</x-master-card>
<x-master-card title="Kontak & Alamat" subtitle="Informasi komunikasi siswa.">
<div class="space-y-4 text-sm text-slate-600">
<div><span class="font-semibold text-slate-800">No. HP:</span> {{ $student->phone_number ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Email:</span> {{ $student->email ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Alamat:</span> {{ $student->address ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Wilayah:</span> {{ collect([$student->village, $student->district, $student->city, $student->province])->filter()->join(', ') ?: '-' }}</div>
<div><span class="font-semibold text-slate-800">Kode Pos:</span> {{ $student->postal_code ?: '-' }}</div>
</div>
</x-master-card>
</div>
<div class="mt-6">
<x-master-card title="Histori Akademik Siswa" subtitle="Riwayat penempatan siswa per tahun angkatan, jurusan, dan kelas.">
@if ($student->academicHistories->isEmpty())
<div class="text-sm text-slate-500">Belum ada histori akademik untuk siswa ini.</div>
@else
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-slate-200">
<thead class="bg-slate-50">
<tr>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">Tahun</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">Jurusan</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">Kelas</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">Status</th>
<th class="px-4 py-3 text-left text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">Periode</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 bg-white">
@foreach ($student->academicHistories as $history)
<tr>
<td class="px-4 py-3 text-sm text-slate-700">{{ $history->academicYear?->name ?: '-' }}</td>
<td class="px-4 py-3 text-sm text-slate-600">{{ $history->department?->name ?: '-' }}</td>
<td class="px-4 py-3 text-sm text-slate-600">{{ $history->classRoom?->name ?: '-' }}</td>
<td class="px-4 py-3 text-sm text-slate-600">
<span class="rounded-full {{ $history->is_current ? 'bg-emerald-100 text-emerald-700' : 'bg-slate-100 text-slate-600' }} px-3 py-1 text-xs font-semibold">
{{ $history->is_current ? 'Aktif Sekarang' : ucfirst($history->status) }}
</span>
</td>
<td class="px-4 py-3 text-sm text-slate-500">
{{ $history->start_date?->format('d-m-Y') ?: '-' }} s/d {{ $history->end_date?->format('d-m-Y') ?: 'Sekarang' }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</x-master-card>
</div>
<div class="mt-6 grid grid-cols-1 gap-6 xl:grid-cols-2">
<x-master-card title="Data Orang Tua / Wali" subtitle="Kelola data ayah, ibu, atau wali siswa.">
<div class="mb-4">
<a href="{{ route('students.parents.create', $student) }}" class="inline-flex items-center rounded-2xl bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-indigo-200 transition hover:bg-indigo-700">
Tambah Orang Tua / Wali
</a>
</div>
@if ($student->parents->isEmpty())
<div class="text-sm text-slate-500">Belum ada data orang tua/wali untuk siswa ini.</div>
@else
<div class="space-y-4">
@foreach ($student->parents as $parent)
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4 text-sm text-slate-600">
<div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
<div>
<div class="font-semibold text-slate-800">{{ ucfirst($parent->relation_type === 'father' ? 'Ayah' : ($parent->relation_type === 'mother' ? 'Ibu' : 'Wali')) }} - {{ $parent->name }}</div>
<div class="mt-1">Pekerjaan: {{ $parent->occupation ?: '-' }}</div>
<div>No. HP: {{ $parent->phone_number ?: '-' }}</div>
<div>Pendidikan: {{ $parent->education ?: '-' }}</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ route('students.parents.edit', [$student, $parent]) }}" class="rounded-xl border border-slate-200 px-3 py-2 text-xs font-semibold text-slate-700 transition hover:bg-slate-100">Edit</a>
@if ($isAdmin)
<form action="{{ route('students.parents.destroy', [$student, $parent]) }}" method="POST" class="delete-form" data-entity="data {{ $parent->name }}">
@csrf
@method('DELETE')
<button type="submit" class="rounded-xl border border-rose-200 px-3 py-2 text-xs font-semibold text-rose-600 transition hover:bg-rose-50">Hapus</button>
</form>
@endif
</div>
</div>
</div>
@endforeach
</div>
@endif
</x-master-card>
<x-master-card title="Dokumen Siswa" subtitle="Kelola file dan status verifikasi dokumen siswa.">
<div class="mb-4">
<a href="{{ route('students.documents.create', $student) }}" class="inline-flex items-center rounded-2xl bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-indigo-200 transition hover:bg-indigo-700">
Tambah Dokumen
</a>
</div>
@if ($student->documents->isEmpty())
<div class="text-sm text-slate-500">Belum ada dokumen siswa yang diunggah.</div>
@else
<div class="space-y-4">
@foreach ($student->documents as $document)
@php
$verificationMap = [
'pending' => 'bg-slate-100 text-slate-600',
'valid' => 'bg-emerald-100 text-emerald-700',
'invalid' => 'bg-rose-100 text-rose-700',
'revision' => 'bg-amber-100 text-amber-700',
];
@endphp
<div class="rounded-3xl border border-slate-200 bg-slate-50 p-5 text-sm text-slate-600 shadow-sm shadow-slate-200/40">
<div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
<div>
<div class="font-semibold text-slate-800">{{ $document->documentType?->name ?: '-' }}</div>
<div class="mt-1">File: {{ $document->file_name }}</div>
<div>Format: {{ strtoupper($document->file_extension ?: '-') }}</div>
<div>Ukuran: {{ $document->file_size ? number_format($document->file_size / 1024, 1) . ' KB' : '-' }}</div>
@if ($document->verifiedBy)
<div>Diverifikasi oleh: {{ $document->verifiedBy->name }}</div>
@endif
<div class="mt-2 flex flex-wrap gap-2">
<span class="rounded-full px-3 py-1 text-xs font-semibold {{ $verificationMap[$document->verification_status] ?? 'bg-slate-100 text-slate-600' }}">
{{ ucfirst($document->verification_status) }}
</span>
@if ($document->verified_at)
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-semibold text-slate-600">
Diverifikasi {{ $document->verified_at->format('d-m-Y H:i') }}
</span>
@endif
</div>
@if ($document->verification_note)
<div class="mt-2 rounded-xl bg-white px-3 py-2 text-xs text-slate-500">
Catatan: {{ $document->verification_note }}
</div>
@endif
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ route('students.documents.preview', $document) }}" class="rounded-xl border border-indigo-200 px-3 py-2 text-xs font-semibold text-indigo-700 transition hover:bg-indigo-50">Lihat</a>
<a href="{{ route('students.documents.download', $document) }}" class="rounded-xl border border-sky-200 px-3 py-2 text-xs font-semibold text-sky-700 transition hover:bg-sky-50">Download</a>
<a href="{{ route('students.documents.edit', [$student, $document]) }}" class="rounded-xl border border-slate-200 px-3 py-2 text-xs font-semibold text-slate-700 transition hover:bg-slate-100">Edit</a>
@if ($isAdmin)
<form action="{{ route('students.documents.quick-verify', [$student, $document]) }}" method="POST" class="inline-flex gap-2">
@csrf
<input type="hidden" name="verification_status" value="valid">
<input type="hidden" name="verification_note" value="Dokumen dinyatakan valid.">
<button type="submit" @disabled($document->verification_status === 'valid') class="rounded-xl border border-emerald-200 px-3 py-2 text-xs font-semibold text-emerald-700 transition hover:bg-emerald-50 disabled:cursor-not-allowed disabled:bg-emerald-100 disabled:text-emerald-500">Valid</button>
</form>
<form action="{{ route('students.documents.quick-verify', [$student, $document]) }}" method="POST" class="inline-flex gap-2">
@csrf
<input type="hidden" name="verification_status" value="revision">
<input type="hidden" name="verification_note" value="Dokumen perlu revisi.">
<button type="submit" @disabled($document->verification_status === 'revision') class="rounded-xl border border-amber-200 px-3 py-2 text-xs font-semibold text-amber-700 transition hover:bg-amber-50 disabled:cursor-not-allowed disabled:bg-amber-100 disabled:text-amber-500">Revisi</button>
</form>
<form action="{{ route('students.documents.quick-verify', [$student, $document]) }}" method="POST" class="inline-flex gap-2">
@csrf
<input type="hidden" name="verification_status" value="invalid">
<input type="hidden" name="verification_note" value="Dokumen dinyatakan tidak valid.">
<button type="submit" @disabled($document->verification_status === 'invalid') class="rounded-xl border border-rose-200 px-3 py-2 text-xs font-semibold text-rose-700 transition hover:bg-rose-50 disabled:cursor-not-allowed disabled:bg-rose-100 disabled:text-rose-500">Invalid</button>
</form>
<form action="{{ route('students.documents.destroy', [$student, $document]) }}" method="POST" class="delete-form" data-entity="dokumen {{ $document->file_name }}">
@csrf
@method('DELETE')
<button type="submit" class="rounded-xl border border-rose-200 px-3 py-2 text-xs font-semibold text-rose-600 transition hover:bg-rose-50">Hapus</button>
</form>
@endif
</div>
</div>
</div>
@endforeach
</div>
@endif
</x-master-card>
</div>
<div class="mt-6 flex flex-wrap items-center gap-3">
<a href="{{ route('students.edit', $student) }}" class="rounded-2xl bg-indigo-600 px-5 py-3 text-sm font-semibold text-white shadow-lg shadow-indigo-200 transition hover:bg-indigo-700">Edit Siswa</a>
<a href="{{ route('students.index') }}" class="rounded-2xl border border-slate-200 px-5 py-3 text-sm font-semibold text-slate-700 transition hover:bg-slate-50">Kembali</a>
</div>
</x-master-page>