mobile
This commit is contained in:
parent
3201648b16
commit
ca05c2459a
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// app/Http/Controllers/admin/AbsensiKegiatanController.php
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// app/Http/Controllers/admin/KategoriKegiatanController.php
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// app/Http/Controllers/admin/KegiatanController.php
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public function index(Request $request)
|
|||
'total_data' => Kepulangan::count(),
|
||||
'menunggu_approval' => Kepulangan::where('status', 'Menunggu')->count(),
|
||||
'sedang_izin' => Kepulangan::aktif()->count(),
|
||||
'over_limit_santri' => $this->getOverLimitSantri()->count(),
|
||||
'over_limit_santri' => count(Kepulangan::getSantriOverLimit()),
|
||||
];
|
||||
|
||||
// Get unique years for filter
|
||||
|
|
@ -58,13 +58,17 @@ public function index(Request $request)
|
|||
->pluck('tahun');
|
||||
|
||||
// Get santri yang over limit untuk highlight
|
||||
$santriOverLimit = $this->getOverLimitSantri()->pluck('total_hari', 'id_santri');
|
||||
$santriOverLimit = Kepulangan::getSantriOverLimit();
|
||||
|
||||
// Get settings untuk info periode
|
||||
$settings = Kepulangan::getSettings();
|
||||
|
||||
return view('admin.kepulangan.index', compact(
|
||||
'kepulangan',
|
||||
'stats',
|
||||
'tahunList',
|
||||
'santriOverLimit'
|
||||
'santriOverLimit',
|
||||
'settings'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +81,9 @@ public function create()
|
|||
->orderBy('nama_lengkap')
|
||||
->get();
|
||||
|
||||
return view('admin.kepulangan.create', compact('santriList'));
|
||||
$settings = Kepulangan::getSettings();
|
||||
|
||||
return view('admin.kepulangan.create', compact('santriList', 'settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,11 +108,21 @@ public function store(Request $request)
|
|||
'alasan.max' => 'Alasan maksimal 500 karakter.',
|
||||
]);
|
||||
|
||||
// Create kepulangan
|
||||
Kepulangan::create($validated);
|
||||
// Create kepulangan (durasi_izin akan otomatis dihitung di model)
|
||||
$kepulangan = Kepulangan::create($validated);
|
||||
|
||||
// Check apakah over limit
|
||||
$kuota = Kepulangan::getSisaKuotaSantri($validated['id_santri']);
|
||||
$message = 'Izin kepulangan berhasil diajukan.';
|
||||
|
||||
if ($kuota['status'] === 'melebihi') {
|
||||
$message .= ' ⚠️ PERHATIAN: Santri ini sudah melebihi kuota ' . $kuota['kuota_maksimal'] . ' hari per tahun (Total: ' . $kuota['total_terpakai'] . ' hari).';
|
||||
} elseif ($kuota['status'] === 'hampir_habis') {
|
||||
$message .= ' ⚠️ Kuota hampir habis. Sisa: ' . $kuota['sisa_kuota'] . ' hari.';
|
||||
}
|
||||
|
||||
return redirect()->route('admin.kepulangan.index')
|
||||
->with('success', 'Izin kepulangan berhasil diajukan.');
|
||||
->with('success', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,14 +130,22 @@ public function store(Request $request)
|
|||
*/
|
||||
public function show($id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan (KP001, KP002, dst)
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)
|
||||
->with('santri')
|
||||
->firstOrFail();
|
||||
|
||||
// Get detail kuota santri
|
||||
$kuotaSantri = Kepulangan::getSisaKuotaSantri($kepulangan->id_santri);
|
||||
|
||||
// Get settings
|
||||
$settings = Kepulangan::getSettings();
|
||||
|
||||
// Get detail izin tahun ini
|
||||
$tahunSekarang = Carbon::now()->year;
|
||||
$detailIzin = $this->getDetailIzinSantri($kepulangan->id_santri, $tahunSekarang);
|
||||
$detailIzin = $this->getDetailIzinSantri(
|
||||
$kepulangan->id_santri,
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
);
|
||||
|
||||
// Get history kepulangan santri (exclude current)
|
||||
$history = Kepulangan::where('id_santri', $kepulangan->id_santri)
|
||||
|
|
@ -132,8 +156,10 @@ public function show($id_kepulangan)
|
|||
|
||||
return view('admin.kepulangan.show', compact(
|
||||
'kepulangan',
|
||||
'kuotaSantri',
|
||||
'detailIzin',
|
||||
'history'
|
||||
'history',
|
||||
'settings'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -142,10 +168,8 @@ public function show($id_kepulangan)
|
|||
*/
|
||||
public function edit($id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
// Hanya bisa edit jika status Menunggu
|
||||
if ($kepulangan->status !== 'Menunggu') {
|
||||
return redirect()->route('admin.kepulangan.index')
|
||||
->with('error', 'Hanya izin dengan status "Menunggu" yang bisa diedit.');
|
||||
|
|
@ -155,7 +179,15 @@ public function edit($id_kepulangan)
|
|||
->orderBy('nama_lengkap')
|
||||
->get();
|
||||
|
||||
return view('admin.kepulangan.edit', compact('kepulangan', 'santriList'));
|
||||
$settings = Kepulangan::getSettings();
|
||||
$kuotaSantri = Kepulangan::getSisaKuotaSantri($kepulangan->id_santri);
|
||||
|
||||
return view('admin.kepulangan.edit', compact(
|
||||
'kepulangan',
|
||||
'santriList',
|
||||
'settings',
|
||||
'kuotaSantri'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -163,10 +195,8 @@ public function edit($id_kepulangan)
|
|||
*/
|
||||
public function update(Request $request, $id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
// Hanya bisa update jika status Menunggu
|
||||
if ($kepulangan->status !== 'Menunggu') {
|
||||
return redirect()->route('admin.kepulangan.index')
|
||||
->with('error', 'Hanya izin dengan status "Menunggu" yang bisa diubah.');
|
||||
|
|
@ -184,10 +214,19 @@ public function update(Request $request, $id_kepulangan)
|
|||
'alasan.min' => 'Alasan minimal 10 karakter.',
|
||||
]);
|
||||
|
||||
// Update (durasi_izin akan otomatis dihitung ulang di model)
|
||||
$kepulangan->update($validated);
|
||||
|
||||
return redirect()->route('admin.kepulangan.index')
|
||||
->with('success', 'Data kepulangan berhasil diperbarui.');
|
||||
// Check apakah over limit setelah update
|
||||
$kuota = Kepulangan::getSisaKuotaSantri($kepulangan->id_santri);
|
||||
$message = 'Data kepulangan berhasil diperbarui.';
|
||||
|
||||
if ($kuota['status'] === 'melebihi') {
|
||||
$message .= ' ⚠️ PERHATIAN: Santri ini sudah melebihi kuota ' . $kuota['kuota_maksimal'] . ' hari.';
|
||||
}
|
||||
|
||||
return redirect()->route('admin.kepulangan.show', $id_kepulangan)
|
||||
->with('success', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -195,10 +234,8 @@ public function update(Request $request, $id_kepulangan)
|
|||
*/
|
||||
public function destroy($id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
// Hanya bisa hapus jika status Menunggu atau Ditolak
|
||||
if (!in_array($kepulangan->status, ['Menunggu', 'Ditolak'])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
|
|
@ -219,7 +256,6 @@ public function destroy($id_kepulangan)
|
|||
*/
|
||||
public function approve(Request $request, $id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
if ($kepulangan->status !== 'Menunggu') {
|
||||
|
|
@ -229,7 +265,6 @@ public function approve(Request $request, $id_kepulangan)
|
|||
], 400);
|
||||
}
|
||||
|
||||
// Update status - catatan opsional (tidak perlu validasi)
|
||||
$kepulangan->update([
|
||||
'status' => 'Disetujui',
|
||||
'approved_by' => Auth::user()->name,
|
||||
|
|
@ -248,10 +283,8 @@ public function approve(Request $request, $id_kepulangan)
|
|||
*/
|
||||
public function reject(Request $request, $id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
// Validasi alasan penolakan (wajib diisi minimal 10 karakter)
|
||||
$validated = $request->validate([
|
||||
'alasan_penolakan' => 'required|string|min:10',
|
||||
], [
|
||||
|
|
@ -280,11 +313,10 @@ public function reject(Request $request, $id_kepulangan)
|
|||
}
|
||||
|
||||
/**
|
||||
* Complete kepulangan (mark as selesai)
|
||||
* Complete kepulangan
|
||||
*/
|
||||
public function complete($id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)->firstOrFail();
|
||||
|
||||
if ($kepulangan->status !== 'Disetujui') {
|
||||
|
|
@ -294,9 +326,7 @@ public function complete($id_kepulangan)
|
|||
], 400);
|
||||
}
|
||||
|
||||
$kepulangan->update([
|
||||
'status' => 'Selesai',
|
||||
]);
|
||||
$kepulangan->update(['status' => 'Selesai']);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
|
|
@ -309,7 +339,6 @@ public function complete($id_kepulangan)
|
|||
*/
|
||||
public function print($id_kepulangan)
|
||||
{
|
||||
// Cari data berdasarkan id_kepulangan
|
||||
$kepulangan = Kepulangan::where('id_kepulangan', $id_kepulangan)
|
||||
->with('santri')
|
||||
->firstOrFail();
|
||||
|
|
@ -332,7 +361,7 @@ public function print($id_kepulangan)
|
|||
}
|
||||
|
||||
/**
|
||||
* API: Get santri data with penggunaan izin
|
||||
* API: Get santri data with penggunaan kuota
|
||||
*/
|
||||
public function getSantriData($idSantri)
|
||||
{
|
||||
|
|
@ -345,36 +374,164 @@ public function getSantriData($idSantri)
|
|||
], 404);
|
||||
}
|
||||
|
||||
$tahunSekarang = Carbon::now()->year;
|
||||
$penggunaanIzin = $this->getDetailIzinSantri($idSantri, $tahunSekarang);
|
||||
$kuotaSantri = Kepulangan::getSisaKuotaSantri($idSantri);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'santri' => $santri,
|
||||
'penggunaan_izin' => [
|
||||
'total_hari' => $penggunaanIzin['total_hari'],
|
||||
'total_izin' => $penggunaanIzin['total_izin'],
|
||||
'sisa_kuota' => $penggunaanIzin['sisa_kuota'],
|
||||
'over_limit' => $penggunaanIzin['over_limit'],
|
||||
]
|
||||
'penggunaan_izin' => $kuotaSantri
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Get detail izin santri per tahun
|
||||
* ========================================
|
||||
* FITUR PENGATURAN KUOTA
|
||||
* ========================================
|
||||
*/
|
||||
private function getDetailIzinSantri($idSantri, $tahun)
|
||||
|
||||
/**
|
||||
* Show settings page
|
||||
*/
|
||||
public function settings()
|
||||
{
|
||||
$settings = Kepulangan::getSettings();
|
||||
$resetLogs = Kepulangan::getResetLogs(20);
|
||||
|
||||
// Statistik periode saat ini
|
||||
$totalSantri = Santri::where('status', 'Aktif')->count();
|
||||
$santriOverLimit = Kepulangan::getSantriOverLimit();
|
||||
$totalIzinPeriodeIni = Kepulangan::whereBetween('tanggal_pulang', [
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
])->whereIn('status', ['Disetujui', 'Selesai'])->count();
|
||||
|
||||
return view('admin.kepulangan.settings', compact(
|
||||
'settings',
|
||||
'resetLogs',
|
||||
'totalSantri',
|
||||
'santriOverLimit',
|
||||
'totalIzinPeriodeIni'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings
|
||||
*/
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'kuota_maksimal' => 'required|integer|min:1|max:365',
|
||||
'periode_mulai' => 'required|date',
|
||||
'periode_akhir' => 'required|date|after:periode_mulai',
|
||||
], [
|
||||
'kuota_maksimal.required' => 'Kuota maksimal wajib diisi.',
|
||||
'kuota_maksimal.min' => 'Kuota minimal 1 hari.',
|
||||
'kuota_maksimal.max' => 'Kuota maksimal 365 hari.',
|
||||
'periode_mulai.required' => 'Periode mulai wajib diisi.',
|
||||
'periode_akhir.required' => 'Periode akhir wajib diisi.',
|
||||
'periode_akhir.after' => 'Periode akhir harus setelah periode mulai.',
|
||||
]);
|
||||
|
||||
Kepulangan::updateSettings(
|
||||
$validated['kuota_maksimal'],
|
||||
$validated['periode_mulai'],
|
||||
$validated['periode_akhir']
|
||||
);
|
||||
|
||||
return redirect()->route('admin.kepulangan.settings')
|
||||
->with('success', 'Pengaturan kuota berhasil diperbarui.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset kuota satu santri
|
||||
*/
|
||||
public function resetKuotaSantri(Request $request, $idSantri)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'catatan' => 'nullable|string|max:500',
|
||||
]);
|
||||
|
||||
$santri = Santri::where('id_santri', $idSantri)->firstOrFail();
|
||||
|
||||
$result = Kepulangan::resetKuotaSantri(
|
||||
$idSantri,
|
||||
Auth::user()->name,
|
||||
$validated['catatan'] ?? 'Reset kuota individual untuk ' . $santri->nama_lengkap
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Kuota santri ' . $santri->nama_lengkap . ' berhasil direset. Total ' . $result['total_hari_direset'] . ' hari telah direset.'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset kuota semua santri
|
||||
*/
|
||||
public function resetKuotaSemuaSantri(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'catatan' => 'nullable|string|max:500',
|
||||
'konfirmasi' => 'required|accepted',
|
||||
], [
|
||||
'konfirmasi.accepted' => 'Anda harus mencentang konfirmasi untuk melanjutkan reset massal.',
|
||||
]);
|
||||
|
||||
$result = Kepulangan::resetKuotaSemuaSantri(
|
||||
Auth::user()->name,
|
||||
$validated['catatan'] ?? 'Reset kuota tahunan massal'
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Kuota berhasil direset untuk ' . $result['total_santri'] . ' santri. Total ' . $result['total_hari_direset'] . ' hari telah direset.',
|
||||
'data' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show list santri over limit
|
||||
*/
|
||||
public function santriOverLimit()
|
||||
{
|
||||
$settings = Kepulangan::getSettings();
|
||||
$santriOverLimitIds = Kepulangan::getSantriOverLimit();
|
||||
|
||||
$santriList = Santri::whereIn('id_santri', array_keys($santriOverLimitIds))
|
||||
->with(['kepulangan' => function($query) use ($settings) {
|
||||
$query->whereBetween('tanggal_pulang', [
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
])->whereIn('status', ['Disetujui', 'Selesai']);
|
||||
}])
|
||||
->get()
|
||||
->map(function($santri) use ($santriOverLimitIds) {
|
||||
$kuota = Kepulangan::getSisaKuotaSantri($santri->id_santri);
|
||||
$santri->total_hari_izin = $santriOverLimitIds[$santri->id_santri];
|
||||
$santri->kuota_info = $kuota;
|
||||
return $santri;
|
||||
})
|
||||
->sortByDesc('total_hari_izin');
|
||||
|
||||
return view('admin.kepulangan.over-limit', compact('santriList', 'settings'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Get detail izin santri
|
||||
*/
|
||||
private function getDetailIzinSantri($idSantri, $periodeMulai, $periodeAkhir)
|
||||
{
|
||||
$kepulanganList = Kepulangan::where('id_santri', $idSantri)
|
||||
->where('status', 'Disetujui')
|
||||
->whereYear('tanggal_pulang', $tahun)
|
||||
->whereIn('status', ['Disetujui', 'Selesai'])
|
||||
->whereBetween('tanggal_pulang', [$periodeMulai, $periodeAkhir])
|
||||
->orderBy('tanggal_pulang', 'desc')
|
||||
->get();
|
||||
|
||||
$settings = Kepulangan::getSettings();
|
||||
$totalHari = $kepulanganList->sum('durasi_izin');
|
||||
$totalIzin = $kepulanganList->count();
|
||||
$sisaKuota = max(0, 12 - $totalHari);
|
||||
$overLimit = $totalHari > 12;
|
||||
$sisaKuota = max(0, $settings->kuota_maksimal - $totalHari);
|
||||
$overLimit = $totalHari > $settings->kuota_maksimal;
|
||||
|
||||
$details = $kepulanganList->map(function($item) {
|
||||
return [
|
||||
|
|
@ -382,6 +539,7 @@ private function getDetailIzinSantri($idSantri, $tahun)
|
|||
'tanggal' => $item->tanggal_pulang_formatted . ' - ' . $item->tanggal_kembali_formatted,
|
||||
'durasi' => $item->durasi_izin,
|
||||
'alasan' => $item->alasan,
|
||||
'status' => $item->status,
|
||||
];
|
||||
});
|
||||
|
||||
|
|
@ -393,19 +551,4 @@ private function getDetailIzinSantri($idSantri, $tahun)
|
|||
'details' => $details,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper: Get santri yang over limit
|
||||
*/
|
||||
private function getOverLimitSantri()
|
||||
{
|
||||
$tahunSekarang = Carbon::now()->year;
|
||||
|
||||
return Kepulangan::selectRaw('id_santri, SUM(durasi_izin) as total_hari')
|
||||
->where('status', 'Disetujui')
|
||||
->whereYear('tanggal_pulang', $tahunSekarang)
|
||||
->groupBy('id_santri')
|
||||
->having('total_hari', '>', 12)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// app/Http/Controllers/admin/RiwayatKegiatanController.php
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
use App\Models\Santri;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SantriController extends Controller
|
||||
{
|
||||
|
|
@ -46,6 +47,7 @@ public function index(Request $request)
|
|||
'jenis_kelamin',
|
||||
'kelas',
|
||||
'status',
|
||||
'foto', // TAMBAHAN
|
||||
'created_at'
|
||||
)
|
||||
->orderBy('created_at', 'desc')
|
||||
|
|
@ -87,15 +89,33 @@ public function store(Request $request)
|
|||
'daerah_asal' => 'nullable|string|max:255',
|
||||
'nama_orang_tua' => 'nullable|string|max:255',
|
||||
'nomor_hp_ortu' => 'nullable|string|max:20',
|
||||
'foto' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', // TAMBAHAN: max 2MB
|
||||
], [
|
||||
'nis.unique' => 'NIS sudah digunakan oleh santri lain.',
|
||||
'nama_lengkap.required' => 'Nama lengkap wajib diisi.',
|
||||
'jenis_kelamin.required' => 'Jenis kelamin wajib dipilih.',
|
||||
'kelas.required' => 'Kelas wajib dipilih.',
|
||||
'status.required' => 'Status wajib dipilih.',
|
||||
'foto.image' => 'File harus berupa gambar.',
|
||||
'foto.mimes' => 'Foto harus berformat JPG, JPEG, atau PNG.',
|
||||
'foto.max' => 'Ukuran foto maksimal 2 MB.',
|
||||
]);
|
||||
|
||||
Santri::create($validated);
|
||||
// Buat santri terlebih dahulu untuk mendapatkan id_santri
|
||||
$santri = Santri::create($validated);
|
||||
|
||||
// Handle upload foto
|
||||
if ($request->hasFile('foto')) {
|
||||
$file = $request->file('foto');
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = $santri->id_santri . '.' . $extension;
|
||||
|
||||
// Simpan file ke storage/app/public/santri
|
||||
$path = $file->storeAs('santri', $filename, 'public');
|
||||
|
||||
// Update path foto di database
|
||||
$santri->update(['foto' => $path]);
|
||||
}
|
||||
|
||||
// Clear cache
|
||||
Cache::forget('next_santri_id');
|
||||
|
|
@ -137,14 +157,34 @@ public function update(Request $request, Santri $santri)
|
|||
'daerah_asal' => 'nullable|string|max:255',
|
||||
'nama_orang_tua' => 'nullable|string|max:255',
|
||||
'nomor_hp_ortu' => 'nullable|string|max:20',
|
||||
'foto' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', // TAMBAHAN: max 2MB
|
||||
], [
|
||||
'nis.unique' => 'NIS sudah digunakan oleh santri lain.',
|
||||
'nama_lengkap.required' => 'Nama lengkap wajib diisi.',
|
||||
'jenis_kelamin.required' => 'Jenis kelamin wajib dipilih.',
|
||||
'kelas.required' => 'Kelas wajib dipilih.',
|
||||
'status.required' => 'Status wajib dipilih.',
|
||||
'foto.image' => 'File harus berupa gambar.',
|
||||
'foto.mimes' => 'Foto harus berformat JPG, JPEG, atau PNG.',
|
||||
'foto.max' => 'Ukuran foto maksimal 2 MB.',
|
||||
]);
|
||||
|
||||
// Handle upload foto baru
|
||||
if ($request->hasFile('foto')) {
|
||||
// Hapus foto lama jika ada
|
||||
if ($santri->foto && Storage::disk('public')->exists($santri->foto)) {
|
||||
Storage::disk('public')->delete($santri->foto);
|
||||
}
|
||||
|
||||
$file = $request->file('foto');
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = $santri->id_santri . '.' . $extension;
|
||||
|
||||
// Simpan file ke storage/app/public/santri
|
||||
$path = $file->storeAs('santri', $filename, 'public');
|
||||
$validated['foto'] = $path;
|
||||
}
|
||||
|
||||
$santri->update($validated);
|
||||
|
||||
// Clear cache
|
||||
|
|
@ -162,6 +202,11 @@ public function destroy(Santri $santri)
|
|||
{
|
||||
$namaSantri = $santri->nama_lengkap;
|
||||
|
||||
// Hapus foto jika ada
|
||||
if ($santri->foto && Storage::disk('public')->exists($santri->foto)) {
|
||||
Storage::disk('public')->delete($santri->foto);
|
||||
}
|
||||
|
||||
$santri->delete();
|
||||
|
||||
// Clear cache
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
// app/Http/Controllers/Api/ApiAuthController.php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use App\Models\Santri;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ApiAuthController extends Controller
|
||||
{
|
||||
/**
|
||||
* Login Santri/Wali via Mobile
|
||||
*
|
||||
* Request:
|
||||
* - id_santri (username)
|
||||
* - password
|
||||
*
|
||||
* Response:
|
||||
* - token
|
||||
* - user (name, role, role_id)
|
||||
* - santri (data lengkap santri jika role=santri)
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'id_santri' => 'required|string',
|
||||
'password' => 'required|string',
|
||||
]);
|
||||
|
||||
// Cari user berdasarkan username (id_santri)
|
||||
$user = User::where('username', $request->id_santri)->first();
|
||||
|
||||
// Validasi user dan password
|
||||
if (!$user || !Hash::check($request->password, $user->password)) {
|
||||
throw ValidationException::withMessages([
|
||||
'id_santri' => ['ID Santri atau password salah.'],
|
||||
]);
|
||||
}
|
||||
|
||||
// Cek apakah user adalah santri atau wali
|
||||
if (!in_array($user->role, ['santri', 'wali'])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Akun ini tidak memiliki akses ke aplikasi mobile.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
// Hapus token lama (optional, untuk keamanan)
|
||||
$user->tokens()->delete();
|
||||
|
||||
// Buat token baru
|
||||
$token = $user->createToken('mobile-app')->plainTextToken;
|
||||
|
||||
// Prepare response data
|
||||
$responseData = [
|
||||
'success' => true,
|
||||
'message' => 'Login berhasil',
|
||||
'token' => $token,
|
||||
'user' => [
|
||||
'name' => $user->name,
|
||||
'role' => $user->role,
|
||||
'role_id' => $user->role_id,
|
||||
],
|
||||
];
|
||||
|
||||
// Jika santri, sertakan data santri
|
||||
if ($user->role === 'santri') {
|
||||
$santri = Santri::where('id_santri', $user->role_id)
|
||||
->select([
|
||||
'id_santri',
|
||||
'nis',
|
||||
'nama_lengkap',
|
||||
'jenis_kelamin',
|
||||
'kelas',
|
||||
'status',
|
||||
'alamat_santri',
|
||||
'daerah_asal',
|
||||
'nama_orang_tua',
|
||||
'nomor_hp_ortu',
|
||||
'foto'
|
||||
])
|
||||
->first();
|
||||
|
||||
$responseData['santri'] = $santri;
|
||||
}
|
||||
|
||||
return response()->json($responseData, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout - Hapus token
|
||||
*/
|
||||
public function logout(Request $request)
|
||||
{
|
||||
// Hapus token yang sedang digunakan
|
||||
$request->user()->currentAccessToken()->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Logout berhasil',
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Profile Santri yang sedang login
|
||||
*/
|
||||
public function profile(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if ($user->role !== 'santri') {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Hanya santri yang bisa mengakses profil.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$santri = Santri::where('id_santri', $user->role_id)
|
||||
->select([
|
||||
'id_santri',
|
||||
'nis',
|
||||
'nama_lengkap',
|
||||
'jenis_kelamin',
|
||||
'kelas',
|
||||
'status',
|
||||
'alamat_santri',
|
||||
'daerah_asal',
|
||||
'nama_orang_tua',
|
||||
'nomor_hp_ortu',
|
||||
'foto',
|
||||
'created_at'
|
||||
])
|
||||
->first();
|
||||
|
||||
if (!$santri) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Data santri tidak ditemukan.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'id_santri' => $santri->id_santri,
|
||||
'nis' => $santri->nis,
|
||||
'nama_lengkap' => $santri->nama_lengkap,
|
||||
'jenis_kelamin' => $santri->jenis_kelamin,
|
||||
'kelas' => $santri->kelas,
|
||||
'status' => $santri->status,
|
||||
'alamat_santri' => $santri->alamat_santri,
|
||||
'daerah_asal' => $santri->daerah_asal,
|
||||
'nama_orang_tua' => $santri->nama_orang_tua,
|
||||
'nomor_hp_ortu' => $santri->nomor_hp_ortu,
|
||||
'foto_url' => $santri->foto_url, // Accessor dari Model Santri
|
||||
'bergabung_sejak' => $santri->created_at->format('d F Y'),
|
||||
]
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\Santri;
|
||||
use App\Models\User;
|
||||
use App\Models\RiwayatPelanggaran;
|
||||
use App\Models\Berita;
|
||||
use App\Models\KesehatanSantri;
|
||||
use App\Models\Kepulangan;
|
||||
use App\Models\Capaian;
|
||||
use App\Models\Semester;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class DashboardController extends Controller
|
||||
|
|
@ -31,104 +32,263 @@ public function admin()
|
|||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error di Dashboard Admin: ' . $e->getMessage());
|
||||
|
||||
return response()->view('errors.500', [
|
||||
'error' => 'Terjadi kesalahan saat memuat dashboard',
|
||||
'message' => $e->getMessage()
|
||||
], 500);
|
||||
abort(500, 'Terjadi kesalahan saat memuat dashboard Admin: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard Santri/Wali - OPTIMIZED ✅
|
||||
* Dashboard Santri/Wali - FIXED VERSION ✅
|
||||
*/
|
||||
public function santri()
|
||||
{
|
||||
try {
|
||||
$user = Auth::user();
|
||||
|
||||
Log::info('=== DASHBOARD SANTRI START ===');
|
||||
Log::info('User ID: ' . $user->id);
|
||||
Log::info('Role: ' . $user->role);
|
||||
Log::info('Role ID: ' . $user->role_id);
|
||||
|
||||
// Validasi role
|
||||
if (!in_array($user->role, ['santri', 'wali'])) {
|
||||
Log::error('Role tidak sesuai: ' . $user->role);
|
||||
abort(403, 'Akses ditolak. Role Anda: ' . $user->role);
|
||||
}
|
||||
|
||||
// ✅ QUERY OPTIMIZED - Ambil data santri dengan kolom minimal
|
||||
// ✅ Ambil data santri
|
||||
$santri = Santri::where('id_santri', $user->role_id)
|
||||
->select('id_santri', 'nama_lengkap', 'kelas')
|
||||
->firstOrFail();
|
||||
->first();
|
||||
|
||||
if (!$santri) {
|
||||
Log::error('Santri tidak ditemukan dengan role_id: ' . $user->role_id);
|
||||
abort(404, 'Data santri tidak ditemukan.');
|
||||
}
|
||||
|
||||
Log::info('Santri ditemukan: ' . $santri->nama_lengkap);
|
||||
|
||||
$idSantri = $santri->id_santri;
|
||||
$today = Carbon::today();
|
||||
$weekAgo = Carbon::now()->subDays(7);
|
||||
|
||||
// ✅ PARALLEL QUERIES - Eksekusi query secara bersamaan untuk performa
|
||||
// ✅ Ambil semester aktif dengan FALLBACK
|
||||
$semesterAktif = null;
|
||||
try {
|
||||
$semesterAktif = Semester::where('status', 'aktif')
|
||||
->select('id_semester', 'nama_semester', 'tahun_ajaran')
|
||||
->first();
|
||||
|
||||
if (!$semesterAktif) {
|
||||
$semesterAktif = Semester::select('id_semester', 'nama_semester', 'tahun_ajaran')
|
||||
->orderBy('tahun_ajaran', 'desc')
|
||||
->orderBy('periode', 'desc')
|
||||
->first();
|
||||
}
|
||||
|
||||
Log::info('Semester aktif: ' . ($semesterAktif ? $semesterAktif->nama_semester : 'Tidak ada'));
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error mengambil semester: ' . $e->getMessage());
|
||||
$semesterAktif = null;
|
||||
}
|
||||
|
||||
// ✅ AMBIL PROGRES AL-QUR'AN dengan FALLBACK
|
||||
$progresAlquran = 0;
|
||||
try {
|
||||
$query = Capaian::where('id_santri', $idSantri);
|
||||
|
||||
if ($semesterAktif) {
|
||||
$query->where('id_semester', $semesterAktif->id_semester);
|
||||
}
|
||||
|
||||
$progresAlquran = $query->whereHas('materi', function($q) {
|
||||
$q->where('kategori', 'Al-Qur\'an');
|
||||
})->avg('persentase') ?? 0;
|
||||
|
||||
Log::info('Progres Al-Quran: ' . $progresAlquran);
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error progres Al-Quran: ' . $e->getMessage());
|
||||
$progresAlquran = 0;
|
||||
}
|
||||
|
||||
// ✅ AMBIL PROGRES HADIST dengan FALLBACK
|
||||
$progresHadist = 0;
|
||||
try {
|
||||
$query = Capaian::where('id_santri', $idSantri);
|
||||
|
||||
if ($semesterAktif) {
|
||||
$query->where('id_semester', $semesterAktif->id_semester);
|
||||
}
|
||||
|
||||
$progresHadist = $query->whereHas('materi', function($q) {
|
||||
$q->where('kategori', 'Hadist');
|
||||
})->avg('persentase') ?? 0;
|
||||
|
||||
Log::info('Progres Hadist: ' . $progresHadist);
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error progres Hadist: ' . $e->getMessage());
|
||||
$progresHadist = 0;
|
||||
}
|
||||
|
||||
// ✅ AMBIL PROGRES MATERI TAMBAHAN dengan FALLBACK
|
||||
$progresMateriTambahan = 0;
|
||||
try {
|
||||
$query = Capaian::where('id_santri', $idSantri);
|
||||
|
||||
if ($semesterAktif) {
|
||||
$query->where('id_semester', $semesterAktif->id_semester);
|
||||
}
|
||||
|
||||
$progresMateriTambahan = $query->whereHas('materi', function($q) {
|
||||
$q->where('kategori', 'Materi Tambahan');
|
||||
})->avg('persentase') ?? 0;
|
||||
|
||||
Log::info('Progres Materi Tambahan: ' . $progresMateriTambahan);
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error progres Materi Tambahan: ' . $e->getMessage());
|
||||
$progresMateriTambahan = 0;
|
||||
}
|
||||
|
||||
// ✅ DATA UNTUK GRAFIK 1: Progress per Materi dengan FALLBACK
|
||||
$capaianPerMateri = collect([]);
|
||||
try {
|
||||
$query = Capaian::with(['materi' => function($q) {
|
||||
$q->select('id_materi', 'nama_kitab', 'kategori', 'total_halaman');
|
||||
}])
|
||||
->where('id_santri', $idSantri);
|
||||
|
||||
if ($semesterAktif) {
|
||||
$query->where('id_semester', $semesterAktif->id_semester);
|
||||
}
|
||||
|
||||
$capaianPerMateri = $query->select('id', 'id_materi', 'persentase', 'halaman_selesai')
|
||||
->orderBy('persentase', 'desc')
|
||||
->limit(10)
|
||||
->get();
|
||||
|
||||
Log::info('Capaian per materi: ' . $capaianPerMateri->count() . ' items');
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error capaian per materi: ' . $e->getMessage());
|
||||
$capaianPerMateri = collect([]);
|
||||
}
|
||||
|
||||
// ✅ DATA UNTUK GRAFIK 2: Distribusi Status dengan FALLBACK
|
||||
$distribusiStatus = [
|
||||
'selesai' => 0,
|
||||
'hampir_selesai' => 0,
|
||||
'sedang_berjalan' => 0,
|
||||
'baru_dimulai' => 0,
|
||||
];
|
||||
|
||||
try {
|
||||
$baseQuery = Capaian::where('id_santri', $idSantri);
|
||||
|
||||
if ($semesterAktif) {
|
||||
$baseQuery->where('id_semester', $semesterAktif->id_semester);
|
||||
}
|
||||
|
||||
$distribusiStatus = [
|
||||
'selesai' => (clone $baseQuery)->where('persentase', '>=', 100)->count(),
|
||||
'hampir_selesai' => (clone $baseQuery)->whereBetween('persentase', [75, 99.99])->count(),
|
||||
'sedang_berjalan' => (clone $baseQuery)->whereBetween('persentase', [25, 74.99])->count(),
|
||||
'baru_dimulai' => (clone $baseQuery)->whereBetween('persentase', [0, 24.99])->count(),
|
||||
];
|
||||
|
||||
Log::info('Distribusi status: ' . json_encode($distribusiStatus));
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error distribusi status: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// ✅ Data dashboard utama
|
||||
$data = [
|
||||
'nama_santri' => $santri->nama_lengkap,
|
||||
'kelas' => $santri->kelas,
|
||||
'progres_quran' => 0, // Nanti diisi dari database capaian
|
||||
'progres_hadist' => 0, // Nanti diisi dari database capaian
|
||||
|
||||
// Query langsung untuk saldo uang saku (dari accessor model)
|
||||
'saldo_uang_saku' => $santri->saldo_uang_saku,
|
||||
|
||||
// Query optimized untuk poin pelanggaran
|
||||
'poin_pelanggaran' => RiwayatPelanggaran::where('id_santri', $idSantri)
|
||||
->sum('poin'),
|
||||
'progres_quran' => round($progresAlquran, 1),
|
||||
'progres_hadist' => round($progresHadist, 1),
|
||||
'progres_materi_tambahan' => round($progresMateriTambahan, 1),
|
||||
'saldo_uang_saku' => method_exists($santri, 'getSaldoUangSakuAttribute')
|
||||
? $santri->saldo_uang_saku
|
||||
: 0,
|
||||
'poin_pelanggaran' => RiwayatPelanggaran::where('id_santri', $idSantri)->sum('poin') ?? 0,
|
||||
];
|
||||
|
||||
// ✅ Query status kesehatan (hanya jika sedang dirawat)
|
||||
$statusKesehatan = KesehatanSantri::where('id_santri', $idSantri)
|
||||
->where('status', 'dirawat')
|
||||
->select('id', 'keluhan', 'tanggal_masuk')
|
||||
->orderBy('tanggal_masuk', 'desc')
|
||||
->first();
|
||||
Log::info('Data array: ' . json_encode($data));
|
||||
|
||||
// ✅ Query kepulangan aktif (hanya jika sedang dalam periode pulang)
|
||||
$kepulanganAktif = Kepulangan::where('id_santri', $idSantri)
|
||||
->where('status', 'Disetujui')
|
||||
->whereDate('tanggal_pulang', '<=', $today)
|
||||
->whereDate('tanggal_kembali', '>=', $today)
|
||||
->select('id_kepulangan', 'tanggal_pulang', 'tanggal_kembali', 'alasan')
|
||||
->first();
|
||||
// ✅ Query status kesehatan dengan FALLBACK
|
||||
$statusKesehatan = null;
|
||||
try {
|
||||
$statusKesehatan = KesehatanSantri::where('id_santri', $idSantri)
|
||||
->where('status', 'dirawat')
|
||||
->select('id', 'keluhan', 'tanggal_masuk')
|
||||
->orderBy('tanggal_masuk', 'desc')
|
||||
->first();
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error status kesehatan: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// ✅ Query berita terbaru (7 hari terakhir) - OPTIMIZED
|
||||
$beritaTerbaru = Berita::select('id_berita', 'judul', 'created_at')
|
||||
->where('status', 'published')
|
||||
->where('created_at', '>=', $weekAgo)
|
||||
->where(function($query) use ($santri) {
|
||||
$query->where('target_berita', 'semua')
|
||||
->orWhere(function($q) use ($santri) {
|
||||
$q->where('target_berita', 'kelas_tertentu')
|
||||
->whereJsonContains('target_kelas', $santri->kelas);
|
||||
})
|
||||
->orWhereHas('santriTertentu', function($q) use ($santri) {
|
||||
$q->where('santris.id_santri', $santri->id_santri);
|
||||
});
|
||||
})
|
||||
->orderBy('created_at', 'desc')
|
||||
->limit(5)
|
||||
->get();
|
||||
// ✅ Query kepulangan aktif dengan FALLBACK
|
||||
$kepulanganAktif = null;
|
||||
try {
|
||||
$kepulanganAktif = Kepulangan::where('id_santri', $idSantri)
|
||||
->where('status', 'Disetujui')
|
||||
->whereDate('tanggal_pulang', '<=', $today)
|
||||
->whereDate('tanggal_kembali', '>=', $today)
|
||||
->select('id_kepulangan', 'tanggal_pulang', 'tanggal_kembali', 'alasan')
|
||||
->first();
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error kepulangan aktif: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Return view dengan data yang sudah dioptimasi
|
||||
// ✅ Query berita terbaru dengan FALLBACK
|
||||
$beritaTerbaru = collect([]);
|
||||
try {
|
||||
$beritaTerbaru = Berita::select('id_berita', 'judul', 'created_at')
|
||||
->where('status', 'published')
|
||||
->where('created_at', '>=', $weekAgo)
|
||||
->where(function($query) use ($santri) {
|
||||
$query->where('target_berita', 'semua')
|
||||
->orWhere(function($q) use ($santri) {
|
||||
$q->where('target_berita', 'kelas_tertentu')
|
||||
->whereJsonContains('target_kelas', $santri->kelas);
|
||||
});
|
||||
})
|
||||
->orderBy('created_at', 'desc')
|
||||
->limit(5)
|
||||
->get();
|
||||
|
||||
Log::info('Berita terbaru: ' . $beritaTerbaru->count() . ' items');
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Error berita terbaru: ' . $e->getMessage());
|
||||
$beritaTerbaru = collect([]);
|
||||
}
|
||||
|
||||
Log::info('=== DASHBOARD SANTRI SUCCESS ===');
|
||||
|
||||
// Return view dengan semua data
|
||||
return view('santri.dashboardSantri', compact(
|
||||
'data',
|
||||
'santri',
|
||||
'user',
|
||||
'beritaTerbaru',
|
||||
'statusKesehatan',
|
||||
'kepulanganAktif'
|
||||
'kepulanganAktif',
|
||||
'capaianPerMateri',
|
||||
'distribusiStatus',
|
||||
'semesterAktif'
|
||||
));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('=== ERROR DI DASHBOARD SANTRI ===');
|
||||
Log::error('=== FATAL ERROR DI DASHBOARD SANTRI ===');
|
||||
Log::error('Message: ' . $e->getMessage());
|
||||
Log::error('File: ' . $e->getFile());
|
||||
Log::error('Line: ' . $e->getLine());
|
||||
Log::error('Trace: ' . $e->getTraceAsString());
|
||||
|
||||
return response()->view('errors.500', [
|
||||
'error' => $e->getMessage(),
|
||||
], 500);
|
||||
// Tampilkan error detail jika debug mode
|
||||
if (config('app.debug')) {
|
||||
abort(500, 'Error: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
|
||||
} else {
|
||||
abort(500, 'Terjadi kesalahan saat memuat dashboard. Silakan hubungi administrator.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
// app/Http/Controllers/Santri/RiwayatKegiatanSantriController.php
|
||||
namespace App\Http\Controllers\Santri;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\AbsensiKegiatan;
|
||||
use App\Models\Kegiatan;
|
||||
use App\Models\Santri;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class RiwayatKegiatanSantriController extends Controller
|
||||
{
|
||||
/**
|
||||
* Halaman utama: Jadwal Harian + Riwayat Absensi
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user->role !== 'santri') {
|
||||
abort(403, 'Akses ditolak.');
|
||||
}
|
||||
|
||||
$santri = Santri::where('id_santri', $user->role_id)
|
||||
->select('id_santri', 'nama_lengkap', 'kelas')
|
||||
->firstOrFail();
|
||||
|
||||
$idSantri = $santri->id_santri;
|
||||
$today = Carbon::today();
|
||||
$hariIni = Carbon::now()->locale('id')->dayName; // Senin, Selasa, etc.
|
||||
|
||||
// ✅ JADWAL KEGIATAN HARI INI (Tetap)
|
||||
$jadwalHariIni = Kegiatan::with('kategori')
|
||||
->where('hari', ucfirst($hariIni))
|
||||
->select('kegiatan_id', 'kategori_id', 'nama_kegiatan', 'waktu_mulai', 'waktu_selesai', 'materi')
|
||||
->orderBy('waktu_mulai')
|
||||
->get();
|
||||
|
||||
// ✅ CEK STATUS ABSENSI HARI INI
|
||||
$absensiHariIni = AbsensiKegiatan::where('id_santri', $idSantri)
|
||||
->whereDate('tanggal', $today)
|
||||
->pluck('status', 'kegiatan_id')
|
||||
->toArray();
|
||||
|
||||
// ✅ RIWAYAT ABSENSI (dengan filter)
|
||||
$query = AbsensiKegiatan::with('kegiatan.kategori')
|
||||
->where('id_santri', $idSantri);
|
||||
|
||||
// Filter Bulan
|
||||
if ($request->filled('bulan')) {
|
||||
$bulan = Carbon::parse($request->bulan);
|
||||
$query->whereMonth('tanggal', $bulan->month)
|
||||
->whereYear('tanggal', $bulan->year);
|
||||
}
|
||||
|
||||
// Filter Status
|
||||
if ($request->filled('status')) {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
|
||||
$riwayats = $query->orderBy('tanggal', 'desc')
|
||||
->orderBy('waktu_absen', 'desc')
|
||||
->paginate(15)
|
||||
->appends(request()->query());
|
||||
|
||||
// ✅ STATISTIK KEHADIRAN (30 HARI TERAKHIR)
|
||||
$stats30Hari = AbsensiKegiatan::where('id_santri', $idSantri)
|
||||
->whereDate('tanggal', '>=', Carbon::now()->subDays(30))
|
||||
->select('status', DB::raw('count(*) as total'))
|
||||
->groupBy('status')
|
||||
->pluck('total', 'status')
|
||||
->toArray();
|
||||
|
||||
$totalKegiatan30Hari = array_sum($stats30Hari);
|
||||
$persentaseKehadiran = $totalKegiatan30Hari > 0
|
||||
? round(($stats30Hari['Hadir'] ?? 0) / $totalKegiatan30Hari * 100, 1)
|
||||
: 0;
|
||||
|
||||
// ✅ DATA GRAFIK: Kehadiran per Minggu (4 Minggu Terakhir)
|
||||
$dataGrafikMingguan = [];
|
||||
for ($i = 3; $i >= 0; $i--) {
|
||||
$startWeek = Carbon::now()->subWeeks($i)->startOfWeek();
|
||||
$endWeek = Carbon::now()->subWeeks($i)->endOfWeek();
|
||||
|
||||
$hadir = AbsensiKegiatan::where('id_santri', $idSantri)
|
||||
->whereBetween('tanggal', [$startWeek, $endWeek])
|
||||
->where('status', 'Hadir')
|
||||
->count();
|
||||
|
||||
$total = AbsensiKegiatan::where('id_santri', $idSantri)
|
||||
->whereBetween('tanggal', [$startWeek, $endWeek])
|
||||
->count();
|
||||
|
||||
$dataGrafikMingguan[] = [
|
||||
'minggu' => 'Minggu ' . (4 - $i),
|
||||
'hadir' => $hadir,
|
||||
'total' => $total,
|
||||
'persentase' => $total > 0 ? round($hadir / $total * 100, 1) : 0,
|
||||
];
|
||||
}
|
||||
|
||||
// ✅ STATISTIK PER KATEGORI KEGIATAN
|
||||
$statsByKategori = AbsensiKegiatan::where('id_santri', $idSantri)
|
||||
->join('kegiatans', 'absensi_kegiatans.kegiatan_id', '=', 'kegiatans.kegiatan_id')
|
||||
->join('kategori_kegiatans', 'kegiatans.kategori_id', '=', 'kategori_kegiatans.kategori_id')
|
||||
->select(
|
||||
'kategori_kegiatans.nama_kategori',
|
||||
DB::raw('SUM(CASE WHEN absensi_kegiatans.status = "Hadir" THEN 1 ELSE 0 END) as hadir'),
|
||||
DB::raw('COUNT(*) as total')
|
||||
)
|
||||
->groupBy('kategori_kegiatans.nama_kategori')
|
||||
->get();
|
||||
|
||||
return view('santri.kegiatan.index', compact(
|
||||
'santri',
|
||||
'jadwalHariIni',
|
||||
'absensiHariIni',
|
||||
'riwayats',
|
||||
'stats30Hari',
|
||||
'totalKegiatan30Hari',
|
||||
'persentaseKehadiran',
|
||||
'dataGrafikMingguan',
|
||||
'statsByKategori',
|
||||
'hariIni'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Detail Riwayat Absensi per Kegiatan
|
||||
*/
|
||||
public function show($kegiatan_id)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user->role !== 'santri') {
|
||||
abort(403, 'Akses ditolak.');
|
||||
}
|
||||
|
||||
$santri = Santri::where('id_santri', $user->role_id)
|
||||
->select('id_santri', 'nama_lengkap')
|
||||
->firstOrFail();
|
||||
|
||||
$kegiatan = Kegiatan::with('kategori')
|
||||
->where('kegiatan_id', $kegiatan_id)
|
||||
->firstOrFail();
|
||||
|
||||
// Riwayat absensi untuk kegiatan ini
|
||||
$riwayats = AbsensiKegiatan::where('id_santri', $santri->id_santri)
|
||||
->where('kegiatan_id', $kegiatan_id)
|
||||
->orderBy('tanggal', 'desc')
|
||||
->paginate(20);
|
||||
|
||||
// Statistik kehadiran untuk kegiatan ini
|
||||
$stats = AbsensiKegiatan::where('id_santri', $santri->id_santri)
|
||||
->where('kegiatan_id', $kegiatan_id)
|
||||
->select('status', DB::raw('count(*) as total'))
|
||||
->groupBy('status')
|
||||
->pluck('total', 'status')
|
||||
->toArray();
|
||||
|
||||
$totalAbsensi = array_sum($stats);
|
||||
$persentaseHadir = $totalAbsensi > 0
|
||||
? round(($stats['Hadir'] ?? 0) / $totalAbsensi * 100, 1)
|
||||
: 0;
|
||||
|
||||
return view('santri.kegiatan.show', compact(
|
||||
'santri',
|
||||
'kegiatan',
|
||||
'riwayats',
|
||||
'stats',
|
||||
'totalAbsensi',
|
||||
'persentaseHadir'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ function () use ($user) {
|
|||
'nama_orang_tua',
|
||||
'nomor_hp_ortu',
|
||||
'rfid_uid',
|
||||
'foto', // ✅ TAMBAHAN INI - PENTING!
|
||||
'created_at'
|
||||
])
|
||||
->firstOrFail();
|
||||
|
|
@ -68,8 +69,10 @@ public function edit()
|
|||
'id',
|
||||
'id_santri',
|
||||
'nama_lengkap',
|
||||
'jenis_kelamin', // ✅ TAMBAHAN untuk fallback foto default
|
||||
'alamat_santri',
|
||||
'nomor_hp_ortu'
|
||||
'nomor_hp_ortu',
|
||||
'foto' // ✅ TAMBAHAN INI - PENTING!
|
||||
])
|
||||
->firstOrFail();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
<?php
|
||||
|
||||
// app/Models/AbsensiKegiatan.php
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class AbsensiKegiatan extends Model
|
||||
{
|
||||
|
|
@ -75,7 +76,7 @@ public function scopeKegiatan($query, $kegiatan_id)
|
|||
}
|
||||
|
||||
/**
|
||||
* Accessor: Status Badge
|
||||
* Accessor: Status Badge (HTML - untuk admin)
|
||||
*/
|
||||
public function getStatusBadgeAttribute()
|
||||
{
|
||||
|
|
@ -88,4 +89,55 @@ public function getStatusBadgeAttribute()
|
|||
|
||||
return $badges[$this->status] ?? $this->status;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// ✅ TAMBAHKAN METHOD-METHOD BARU DI BAWAH INI
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Accessor: Tanggal Formatted (untuk view santri)
|
||||
*/
|
||||
public function getTanggalFormattedAttribute()
|
||||
{
|
||||
return Carbon::parse($this->tanggal)->locale('id')->isoFormat('dddd, D MMMM YYYY');
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Waktu Absen Formatted (untuk view santri)
|
||||
*/
|
||||
public function getWaktuAbsenFormattedAttribute()
|
||||
{
|
||||
return $this->waktu_absen ? Carbon::parse($this->waktu_absen)->format('H:i') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Status Badge Class (CSS class only - untuk view santri)
|
||||
*/
|
||||
public function getStatusBadgeClassAttribute()
|
||||
{
|
||||
return match($this->status) {
|
||||
'Hadir' => 'badge-success',
|
||||
'Izin' => 'badge-info',
|
||||
'Sakit' => 'badge-warning',
|
||||
'Alpa' => 'badge-danger',
|
||||
default => 'badge-secondary',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter by date range
|
||||
*/
|
||||
public function scopeDateRange($query, $start, $end)
|
||||
{
|
||||
return $query->whereBetween('tanggal', [$start, $end]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter by month
|
||||
*/
|
||||
public function scopeByMonth($query, $month, $year)
|
||||
{
|
||||
return $query->whereMonth('tanggal', $month)
|
||||
->whereYear('tanggal', $year);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// Models/KategoriKegiatan
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
|
||||
// Models/Kegiatan
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class Kepulangan extends Model
|
||||
{
|
||||
|
|
@ -32,47 +33,61 @@ class Kepulangan extends Model
|
|||
'tanggal_pulang' => 'date',
|
||||
'tanggal_kembali' => 'date',
|
||||
'approved_at' => 'datetime',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Boot method untuk auto-generate ID Kepulangan
|
||||
* Boot method - Auto generate ID & calculate durasi
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
// Generate ID Kepulangan
|
||||
if (empty($model->id_kepulangan)) {
|
||||
$last = Kepulangan::orderBy('id', 'desc')->first();
|
||||
$num = $last ? intval(substr($last->id_kepulangan, 2)) + 1 : 1;
|
||||
$model->id_kepulangan = 'KP' . str_pad($num, 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
// Auto-calculate durasi_izin
|
||||
// PENTING: Hitung durasi_izin otomatis
|
||||
if ($model->tanggal_pulang && $model->tanggal_kembali) {
|
||||
$pulang = Carbon::parse($model->tanggal_pulang);
|
||||
$kembali = Carbon::parse($model->tanggal_kembali);
|
||||
$model->durasi_izin = $pulang->diffInDays($kembali) + 1;
|
||||
$model->durasi_izin = $model->hitungDurasiIzin(
|
||||
$model->tanggal_pulang,
|
||||
$model->tanggal_kembali
|
||||
);
|
||||
}
|
||||
|
||||
// Set tanggal_izin ke hari ini jika tidak diisi
|
||||
// Set tanggal_izin jika kosong
|
||||
if (empty($model->tanggal_izin)) {
|
||||
$model->tanggal_izin = now();
|
||||
}
|
||||
});
|
||||
|
||||
static::updating(function ($model) {
|
||||
// Recalculate durasi_izin saat update
|
||||
// Recalculate durasi_izin saat update tanggal
|
||||
if ($model->isDirty(['tanggal_pulang', 'tanggal_kembali'])) {
|
||||
$pulang = Carbon::parse($model->tanggal_pulang);
|
||||
$kembali = Carbon::parse($model->tanggal_kembali);
|
||||
$model->durasi_izin = $pulang->diffInDays($kembali) + 1;
|
||||
$model->durasi_izin = $model->hitungDurasiIzin(
|
||||
$model->tanggal_pulang,
|
||||
$model->tanggal_kembali
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method untuk menghitung durasi izin dalam hari
|
||||
* Formula: (tanggal_kembali - tanggal_pulang) + 1
|
||||
*/
|
||||
private function hitungDurasiIzin($tanggalPulang, $tanggalKembali)
|
||||
{
|
||||
$pulang = Carbon::parse($tanggalPulang);
|
||||
$kembali = Carbon::parse($tanggalKembali);
|
||||
|
||||
// +1 karena hari pertama juga dihitung
|
||||
return $pulang->diffInDays($kembali) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relasi ke Santri
|
||||
*/
|
||||
|
|
@ -82,52 +97,38 @@ public function santri()
|
|||
}
|
||||
|
||||
/**
|
||||
* Accessor: Format tanggal izin
|
||||
* Accessor: Format tanggal
|
||||
*/
|
||||
public function getTanggalIzinFormattedAttribute()
|
||||
{
|
||||
return $this->tanggal_izin ? $this->tanggal_izin->format('d F Y') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Format tanggal pulang
|
||||
*/
|
||||
public function getTanggalPulangFormattedAttribute()
|
||||
{
|
||||
return $this->tanggal_pulang ? $this->tanggal_pulang->format('d F Y') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Format tanggal kembali
|
||||
*/
|
||||
public function getTanggalKembaliFormattedAttribute()
|
||||
{
|
||||
return $this->tanggal_kembali ? $this->tanggal_kembali->format('d F Y') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Format approved_at
|
||||
*/
|
||||
public function getApprovedAtFormattedAttribute()
|
||||
{
|
||||
return $this->approved_at ? $this->approved_at->format('d F Y H:i') : '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Durasi izin calculated
|
||||
* Accessor: Durasi izin calculated (untuk backward compatibility)
|
||||
*/
|
||||
public function getDurasiIzinCalculatedAttribute()
|
||||
{
|
||||
if ($this->tanggal_pulang && $this->tanggal_kembali) {
|
||||
$pulang = Carbon::parse($this->tanggal_pulang);
|
||||
$kembali = Carbon::parse($this->tanggal_kembali);
|
||||
return $pulang->diffInDays($kembali) + 1;
|
||||
}
|
||||
return $this->durasi_izin ?? 0;
|
||||
return $this->durasi_izin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: Status badge HTML
|
||||
* Accessor: Status badge
|
||||
*/
|
||||
public function getStatusBadgeAttribute()
|
||||
{
|
||||
|
|
@ -137,7 +138,6 @@ public function getStatusBadgeAttribute()
|
|||
'Ditolak' => 'badge-danger',
|
||||
'Selesai' => 'badge-secondary',
|
||||
];
|
||||
|
||||
return $badges[$this->status] ?? 'badge-secondary';
|
||||
}
|
||||
|
||||
|
|
@ -163,24 +163,18 @@ public function getIsTerlambatAttribute()
|
|||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter berdasarkan status
|
||||
* Scopes
|
||||
*/
|
||||
public function scopeStatus($query, $status)
|
||||
{
|
||||
return $query->where('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Filter berdasarkan santri
|
||||
*/
|
||||
public function scopeSantri($query, $idSantri)
|
||||
{
|
||||
return $query->where('id_santri', $idSantri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Kepulangan yang sedang aktif
|
||||
*/
|
||||
public function scopeAktif($query)
|
||||
{
|
||||
$today = Carbon::today();
|
||||
|
|
@ -189,18 +183,12 @@ public function scopeAktif($query)
|
|||
->whereDate('tanggal_kembali', '>=', $today);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Kepulangan yang terlambat
|
||||
*/
|
||||
public function scopeTerlambat($query)
|
||||
{
|
||||
return $query->where('status', 'Disetujui')
|
||||
->whereDate('tanggal_kembali', '<', Carbon::today());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope: Search kepulangan
|
||||
*/
|
||||
public function scopeSearch($query, $search)
|
||||
{
|
||||
return $query->where(function($q) use ($search) {
|
||||
|
|
@ -215,33 +203,285 @@ public function scopeSearch($query, $search)
|
|||
}
|
||||
|
||||
/**
|
||||
* Static method: Get total hari izin per santri per tahun
|
||||
* ========================================
|
||||
* FITUR KUOTA TAHUNAN
|
||||
* ========================================
|
||||
*/
|
||||
public static function getTotalHariIzinSantri($idSantri, $tahun = null)
|
||||
|
||||
/**
|
||||
* Get settings kepulangan (kuota, periode)
|
||||
*/
|
||||
public static function getSettings()
|
||||
{
|
||||
$tahun = $tahun ?? Carbon::now()->year;
|
||||
$settings = DB::table('kepulangan_settings')->latest()->first();
|
||||
|
||||
if (!$settings) {
|
||||
// Create default settings
|
||||
DB::table('kepulangan_settings')->insert([
|
||||
'kuota_maksimal' => 12,
|
||||
'periode_mulai' => now()->startOfYear()->format('Y-m-d'),
|
||||
'periode_akhir' => now()->endOfYear()->format('Y-m-d'),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$settings = DB::table('kepulangan_settings')->latest()->first();
|
||||
}
|
||||
|
||||
return (object) [
|
||||
'id' => $settings->id,
|
||||
'kuota_maksimal' => $settings->kuota_maksimal,
|
||||
'periode_mulai' => Carbon::parse($settings->periode_mulai),
|
||||
'periode_akhir' => Carbon::parse($settings->periode_akhir),
|
||||
'terakhir_reset' => $settings->terakhir_reset ? Carbon::parse($settings->terakhir_reset) : null,
|
||||
'reset_by' => $settings->reset_by,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings kepulangan
|
||||
*/
|
||||
public static function updateSettings($kuotaMaksimal, $periodeMulai, $periodeAkhir)
|
||||
{
|
||||
$existing = DB::table('kepulangan_settings')->latest()->first();
|
||||
|
||||
if ($existing) {
|
||||
DB::table('kepulangan_settings')
|
||||
->where('id', $existing->id)
|
||||
->update([
|
||||
'kuota_maksimal' => $kuotaMaksimal,
|
||||
'periode_mulai' => $periodeMulai,
|
||||
'periode_akhir' => $periodeAkhir,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
} else {
|
||||
DB::table('kepulangan_settings')->insert([
|
||||
'kuota_maksimal' => $kuotaMaksimal,
|
||||
'periode_mulai' => $periodeMulai,
|
||||
'periode_akhir' => $periodeAkhir,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get total hari izin santri dalam periode tertentu
|
||||
*/
|
||||
public static function getTotalHariIzinSantri($idSantri, $periodeMulai = null, $periodeAkhir = null)
|
||||
{
|
||||
if (!$periodeMulai || !$periodeAkhir) {
|
||||
$settings = self::getSettings();
|
||||
$periodeMulai = $settings->periode_mulai;
|
||||
$periodeAkhir = $settings->periode_akhir;
|
||||
}
|
||||
|
||||
return self::where('id_santri', $idSantri)
|
||||
->where('status', 'Disetujui')
|
||||
->whereYear('tanggal_pulang', $tahun)
|
||||
->whereIn('status', ['Disetujui', 'Selesai'])
|
||||
->whereBetween('tanggal_pulang', [$periodeMulai, $periodeAkhir])
|
||||
->sum('durasi_izin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method: Check apakah santri over limit (lebih dari 12 hari/tahun)
|
||||
* Get detail kuota santri
|
||||
*/
|
||||
public static function isOverLimit($idSantri, $tahun = null)
|
||||
public static function getSisaKuotaSantri($idSantri)
|
||||
{
|
||||
$totalHari = self::getTotalHariIzinSantri($idSantri, $tahun);
|
||||
return $totalHari > 12;
|
||||
$settings = self::getSettings();
|
||||
|
||||
$totalTerpakai = self::getTotalHariIzinSantri(
|
||||
$idSantri,
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
);
|
||||
|
||||
$sisaKuota = $settings->kuota_maksimal - $totalTerpakai;
|
||||
$persentase = $settings->kuota_maksimal > 0 ?
|
||||
($totalTerpakai / $settings->kuota_maksimal) * 100 : 0;
|
||||
|
||||
// Tentukan status berdasarkan persentase
|
||||
$status = 'aman'; // 0-80%
|
||||
if ($persentase >= 80 && $persentase < 100) {
|
||||
$status = 'hampir_habis'; // 80-100%
|
||||
} elseif ($persentase >= 100) {
|
||||
$status = 'melebihi'; // >100%
|
||||
}
|
||||
|
||||
// Warna badge
|
||||
$badgeColor = 'success'; // Hijau
|
||||
if ($persentase >= 80 && $persentase < 100) {
|
||||
$badgeColor = 'warning'; // Kuning
|
||||
} elseif ($persentase >= 100) {
|
||||
$badgeColor = 'danger'; // Merah
|
||||
}
|
||||
|
||||
return [
|
||||
'kuota_maksimal' => $settings->kuota_maksimal,
|
||||
'total_terpakai' => $totalTerpakai,
|
||||
'sisa_kuota' => max(0, $sisaKuota),
|
||||
'persentase' => round($persentase, 1),
|
||||
'status' => $status,
|
||||
'badge_color' => $badgeColor,
|
||||
'periode_mulai' => $settings->periode_mulai->format('d M Y'),
|
||||
'periode_akhir' => $settings->periode_akhir->format('d M Y'),
|
||||
'terakhir_reset' => $settings->terakhir_reset ?
|
||||
$settings->terakhir_reset->format('d M Y') : '-',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method: Get sisa kuota izin santri
|
||||
* Check apakah santri over limit
|
||||
*/
|
||||
public static function getSisaKuota($idSantri, $tahun = null)
|
||||
public static function isOverLimit($idSantri)
|
||||
{
|
||||
$totalHari = self::getTotalHariIzinSantri($idSantri, $tahun);
|
||||
return max(0, 12 - $totalHari);
|
||||
$kuota = self::getSisaKuotaSantri($idSantri);
|
||||
return $kuota['status'] === 'melebihi';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list santri yang over limit
|
||||
*/
|
||||
public static function getSantriOverLimit()
|
||||
{
|
||||
$settings = self::getSettings();
|
||||
|
||||
$santriIds = Santri::where('status', 'Aktif')->pluck('id_santri');
|
||||
$overLimitList = [];
|
||||
|
||||
foreach ($santriIds as $idSantri) {
|
||||
$totalHari = self::getTotalHariIzinSantri(
|
||||
$idSantri,
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
);
|
||||
|
||||
if ($totalHari > $settings->kuota_maksimal) {
|
||||
$overLimitList[$idSantri] = $totalHari;
|
||||
}
|
||||
}
|
||||
|
||||
return $overLimitList;
|
||||
}
|
||||
|
||||
/**
|
||||
* ========================================
|
||||
* FITUR RESET KUOTA
|
||||
* ========================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reset kuota untuk satu santri
|
||||
*/
|
||||
public static function resetKuotaSantri($idSantri, $resetBy, $catatan = null)
|
||||
{
|
||||
$settings = self::getSettings();
|
||||
|
||||
// Hitung total hari sebelum reset
|
||||
$totalHariSebelumReset = self::getTotalHariIzinSantri(
|
||||
$idSantri,
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
);
|
||||
|
||||
// Catat log reset
|
||||
DB::table('kepulangan_reset_logs')->insert([
|
||||
'id_santri' => $idSantri,
|
||||
'total_hari_sebelum_reset' => $totalHariSebelumReset,
|
||||
'periode_mulai' => $settings->periode_mulai,
|
||||
'periode_akhir' => $settings->periode_akhir,
|
||||
'kuota_tahunan' => $settings->kuota_maksimal,
|
||||
'jenis_reset' => 'individual',
|
||||
'reset_by' => $resetBy,
|
||||
'catatan' => $catatan,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
// Update semua kepulangan santri yang Disetujui menjadi Selesai
|
||||
// Ini cara "reset" dengan menandai semua izin lama sebagai selesai
|
||||
self::where('id_santri', $idSantri)
|
||||
->where('status', 'Disetujui')
|
||||
->whereBetween('tanggal_pulang', [$settings->periode_mulai, $settings->periode_akhir])
|
||||
->update(['status' => 'Selesai']);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'total_hari_direset' => $totalHariSebelumReset,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset kuota untuk semua santri
|
||||
*/
|
||||
public static function resetKuotaSemuaSantri($resetBy, $catatan = null)
|
||||
{
|
||||
$settings = self::getSettings();
|
||||
|
||||
// Get semua santri aktif
|
||||
$santriIds = Santri::where('status', 'Aktif')->pluck('id_santri');
|
||||
$totalSantri = $santriIds->count();
|
||||
$totalHariDireset = 0;
|
||||
|
||||
foreach ($santriIds as $idSantri) {
|
||||
$totalHari = self::getTotalHariIzinSantri(
|
||||
$idSantri,
|
||||
$settings->periode_mulai,
|
||||
$settings->periode_akhir
|
||||
);
|
||||
|
||||
$totalHariDireset += $totalHari;
|
||||
}
|
||||
|
||||
// Catat log reset massal
|
||||
DB::table('kepulangan_reset_logs')->insert([
|
||||
'id_santri' => null, // Null untuk reset massal
|
||||
'total_hari_sebelum_reset' => $totalHariDireset,
|
||||
'periode_mulai' => $settings->periode_mulai,
|
||||
'periode_akhir' => $settings->periode_akhir,
|
||||
'kuota_tahunan' => $settings->kuota_maksimal,
|
||||
'jenis_reset' => 'massal',
|
||||
'reset_by' => $resetBy,
|
||||
'catatan' => $catatan ?? "Reset massal untuk {$totalSantri} santri",
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
// Update semua kepulangan yang Disetujui menjadi Selesai
|
||||
$jumlahDiupdate = self::whereIn('id_santri', $santriIds)
|
||||
->where('status', 'Disetujui')
|
||||
->whereBetween('tanggal_pulang', [$settings->periode_mulai, $settings->periode_akhir])
|
||||
->update(['status' => 'Selesai']);
|
||||
|
||||
// Update tanggal terakhir reset di settings
|
||||
DB::table('kepulangan_settings')
|
||||
->where('id', $settings->id)
|
||||
->update([
|
||||
'terakhir_reset' => now(),
|
||||
'reset_by' => $resetBy,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'total_santri' => $totalSantri,
|
||||
'total_hari_direset' => $totalHariDireset,
|
||||
'jumlah_izin_diupdate' => $jumlahDiupdate,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get history reset logs
|
||||
*/
|
||||
public static function getResetLogs($limit = 20)
|
||||
{
|
||||
return DB::table('kepulangan_reset_logs')
|
||||
->leftJoin('santris', 'kepulangan_reset_logs.id_santri', '=', 'santris.id_santri')
|
||||
->select(
|
||||
'kepulangan_reset_logs.*',
|
||||
'santris.nama_lengkap'
|
||||
)
|
||||
->orderBy('kepulangan_reset_logs.created_at', 'desc')
|
||||
->limit($limit)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<?php
|
||||
// app/Models/Santri.php - Model untuk Data Santri (LENGKAP)
|
||||
// app/Models/Santri.php - Model untuk Data Santri (DENGAN FOTO)
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
|
|
@ -24,7 +24,8 @@ class Santri extends Model
|
|||
'daerah_asal',
|
||||
'nama_orang_tua',
|
||||
'nomor_hp_ortu',
|
||||
'rfid_uid', // TAMBAHAN BARU
|
||||
'rfid_uid',
|
||||
'foto', // TAMBAHAN BARU
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -246,6 +247,23 @@ public function getTotalKehadiranAttribute()
|
|||
return $this->absensiKegiatans()->where('status', 'Hadir')->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor: URL Foto Santri (BARU)
|
||||
*/
|
||||
public function getFotoUrlAttribute()
|
||||
{
|
||||
if ($this->foto && file_exists(storage_path('app/public/' . $this->foto))) {
|
||||
return asset('storage/' . $this->foto);
|
||||
}
|
||||
|
||||
// Fallback ke gambar default berdasarkan jenis kelamin
|
||||
if ($this->jenis_kelamin === 'Perempuan') {
|
||||
return asset('images/default-female.png');
|
||||
}
|
||||
|
||||
return asset('images/default-male.png');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope untuk filter santri aktif
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
|
@ -13,41 +12,42 @@ class User extends Authenticatable
|
|||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'username', // Ditambahkan
|
||||
'username',
|
||||
'password',
|
||||
'role', // Ditambahkan
|
||||
'role_id', // Ditambahkan
|
||||
'role',
|
||||
'role_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
|
||||
// Helper method untuk cek role
|
||||
/**
|
||||
* Relasi ke Santri
|
||||
*/
|
||||
public function santri()
|
||||
{
|
||||
return $this->belongsTo(Santri::class, 'role_id', 'id_santri');
|
||||
}
|
||||
|
||||
/**
|
||||
* Relasi ke Wali
|
||||
*/
|
||||
public function wali()
|
||||
{
|
||||
return $this->belongsTo(Wali::class, 'role_id', 'id_wali');
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
public function isAdmin()
|
||||
{
|
||||
return $this->role === 'admin';
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
// database/migrations/xxxx_xx_xx_xxxxxx_create_kepulangan_table.php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kepulangan', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('id_kepulangan')->unique(); // KP001, KP002, dst
|
||||
$table->string('id_santri'); // Relasi ke santri (S001, S002, dst)
|
||||
$table->date('tanggal_izin'); // Tanggal pengajuan izin
|
||||
$table->date('tanggal_pulang'); // Tanggal mulai pulang
|
||||
$table->date('tanggal_kembali'); // Tanggal rencana kembali
|
||||
$table->integer('durasi_izin'); // Durasi dalam hari
|
||||
$table->text('alasan'); // Alasan kepulangan
|
||||
$table->enum('status', ['Menunggu', 'Disetujui', 'Ditolak', 'Selesai'])->default('Menunggu');
|
||||
$table->string('approved_by')->nullable(); // Admin yang menyetujui
|
||||
$table->timestamp('approved_at')->nullable(); // Waktu persetujuan
|
||||
$table->text('catatan')->nullable(); // Catatan dari admin
|
||||
$table->timestamps();
|
||||
|
||||
// Foreign key
|
||||
$table->foreign('id_santri')
|
||||
->references('id_santri')
|
||||
->on('santris')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kepulangan');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
// database/migrations/xxxx_xx_xx_create_kepulangan_table.php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kepulangan', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('id_kepulangan', 20)->unique()->index();
|
||||
$table->string('id_santri', 20);
|
||||
$table->date('tanggal_izin');
|
||||
$table->date('tanggal_pulang');
|
||||
$table->date('tanggal_kembali');
|
||||
$table->integer('durasi_izin')->default(0)->comment('Durasi dalam hari');
|
||||
$table->text('alasan');
|
||||
$table->enum('status', ['Menunggu', 'Disetujui', 'Ditolak', 'Selesai'])
|
||||
->default('Menunggu');
|
||||
$table->string('approved_by', 100)->nullable();
|
||||
$table->timestamp('approved_at')->nullable();
|
||||
$table->text('catatan')->nullable()->comment('Catatan approval atau penolakan');
|
||||
$table->timestamps();
|
||||
|
||||
// Foreign key
|
||||
$table->foreign('id_santri')
|
||||
->references('id_santri')
|
||||
->on('santris')
|
||||
->onDelete('cascade')
|
||||
->onUpdate('cascade');
|
||||
|
||||
// Indexes untuk performa
|
||||
$table->index('status');
|
||||
$table->index('tanggal_pulang');
|
||||
$table->index('tanggal_kembali');
|
||||
$table->index(['id_santri', 'status']);
|
||||
$table->index(['tanggal_pulang', 'tanggal_kembali']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kepulangan');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
// database/migrations/xxxx_xx_xx_create_kepulangan_settings_table.php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kepulangan_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->integer('kuota_maksimal')->default(12)->comment('Kuota hari izin per tahun');
|
||||
$table->date('periode_mulai')->comment('Awal periode kuota');
|
||||
$table->date('periode_akhir')->comment('Akhir periode kuota');
|
||||
$table->timestamp('terakhir_reset')->nullable();
|
||||
$table->string('reset_by', 100)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
// Insert default settings
|
||||
DB::table('kepulangan_settings')->insert([
|
||||
'kuota_maksimal' => 12,
|
||||
'periode_mulai' => now()->startOfYear()->format('Y-m-d'),
|
||||
'periode_akhir' => now()->endOfYear()->format('Y-m-d'),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kepulangan_settings');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
// database/migrations/xxxx_xx_xx_create_kepulangan_reset_logs_table.php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('kepulangan_reset_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('id_santri', 20)->nullable()->comment('Null jika reset massal');
|
||||
$table->integer('total_hari_sebelum_reset')->default(0);
|
||||
$table->date('periode_mulai');
|
||||
$table->date('periode_akhir');
|
||||
$table->integer('kuota_tahunan');
|
||||
$table->enum('jenis_reset', ['individual', 'massal'])->default('individual');
|
||||
$table->string('reset_by', 100);
|
||||
$table->text('catatan')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
// Foreign key (nullable untuk reset massal)
|
||||
$table->foreign('id_santri')
|
||||
->references('id_santri')
|
||||
->on('santris')
|
||||
->onDelete('set null')
|
||||
->onUpdate('cascade');
|
||||
|
||||
// Indexes
|
||||
$table->index('id_santri');
|
||||
$table->index('jenis_reset');
|
||||
$table->index('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('kepulangan_reset_logs');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
// database/migrations/YYYY_MM_DD_HHMMSS_add_foto_to_santris_table.php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('santris', function (Blueprint $table) {
|
||||
$table->string('foto')->nullable()->after('rfid_uid');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('santris', function (Blueprint $table) {
|
||||
$table->dropColumn('foto');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -9,6 +9,20 @@
|
|||
<h2><i class="fas fa-plus-circle"></i> Tambah Izin Kepulangan</h2>
|
||||
</div>
|
||||
|
||||
{{-- Info Periode Kuota --}}
|
||||
<div style="background: #E8F7F2; padding: 15px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #6FBA9D;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<strong>📅 Periode Kuota:</strong><br>
|
||||
{{ $settings->periode_mulai->format('d M Y') }} - {{ $settings->periode_akhir->format('d M Y') }}
|
||||
</div>
|
||||
<div>
|
||||
<strong>📊 Kuota Maksimal:</strong><br>
|
||||
{{ $settings->kuota_maksimal }} Hari / Tahun
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul style="margin: 0; padding-left: 20px;">
|
||||
|
|
@ -38,22 +52,34 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
{{-- Info Santri --}}
|
||||
{{-- Info Santri & Kuota --}}
|
||||
<div id="santriInfo" style="display: none; background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #6FBA9D;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">Informasi Santri</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">📋 Informasi Santri & Kuota</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px;">
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Nama:</strong> <span id="santriNama">-</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Kelas:</strong> <span id="santriKelas">-</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Periode:</strong> <span id="santriPeriode">-</span></p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Total Hari Izin Tahun Ini:</strong> <span id="totalHariIzin" style="display: inline-block; background: #81C6E8; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">0 hari</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Sisa Kuota:</strong> <span id="sisaKuota" style="display: inline-block; background: #6FBA9D; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">12 hari</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Kuota Maksimal:</strong> <span id="kuotaMaksimal">-</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Total Terpakai:</strong> <span id="totalTerpakai" class="badge">-</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Sisa Kuota:</strong> <span id="sisaKuota" class="badge">-</span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Progress Bar Kuota --}}
|
||||
<div style="margin-top: 15px;">
|
||||
<label style="font-size: 0.9rem; color: #7F8C8D; margin-bottom: 5px;">Penggunaan Kuota:</label>
|
||||
<div style="width: 100%; height: 20px; background: #E0F0EC; border-radius: 10px; overflow: hidden; position: relative;">
|
||||
<div id="progressBar" style="height: 100%; width: 0%; background: #28a745; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; color: white; font-size: 0.75rem; font-weight: 600;"></div>
|
||||
</div>
|
||||
<small id="progressText" style="color: #7F8C8D; margin-top: 5px; display: block;">0% dari kuota terpakai</small>
|
||||
</div>
|
||||
|
||||
<div id="warningOverLimit" style="display: none; margin-top: 15px; padding: 12px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Peringatan:</strong> Santri ini sudah melebihi batas 12 hari per tahun!
|
||||
<strong>⚠️ PERHATIAN:</strong> <span id="warningText"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -86,23 +112,29 @@ class="form-control"
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Info Durasi --}}
|
||||
<div id="durasiInfo" style="display: none; background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #FF8B94;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">Informasi Durasi Izin</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Durasi Izin:</strong> <span id="durasiHari" style="display: inline-block; background: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">0 hari</span></p>
|
||||
{{-- Info Durasi Izin --}}
|
||||
<div id="durasiInfo" style="display: none; background: #fff3e0; padding: 20px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #ff9800;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">⏱️ Detail Durasi Izin</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px;">
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Durasi Izin</div>
|
||||
<div id="durasiHari" style="font-size: 2rem; font-weight: 700; color: #ff9800;">0</div>
|
||||
<div style="font-size: 0.8rem; color: #7F8C8D;">hari</div>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Total Setelah Izin:</strong> <span id="totalSetelahIzin" style="display: inline-block; background: #6c757d; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">0 hari</span></p>
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Total Setelah Izin</div>
|
||||
<div id="totalSetelahIzin" style="font-size: 2rem; font-weight: 700; color: #2196f3;">0</div>
|
||||
<div style="font-size: 0.8rem; color: #7F8C8D;">hari terpakai</div>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Sisa Kuota Setelah Izin:</strong> <span id="sisaKuotaSetelah" style="display: inline-block; background: #6FBA9D; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">12 hari</span></p>
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Sisa Kuota</div>
|
||||
<div id="sisaKuotaSetelah" style="font-size: 2rem; font-weight: 700; color: #28a745;">12</div>
|
||||
<div style="font-size: 0.8rem; color: #7F8C8D;">hari tersisa</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="warningDurasi" style="display: none; margin-top: 15px; padding: 12px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<span id="warningMessage"></span>
|
||||
<div id="warningDurasi" style="display: none; margin-top: 15px; padding: 12px; background: #ffebee; border: 1px solid #ffcdd2; border-radius: 6px; color: #c62828;">
|
||||
<i class="fas fa-exclamation-circle"></i>
|
||||
<strong>⚠️ PERHATIAN:</strong> <span id="warningDurasiMessage"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -141,18 +173,19 @@ class="form-control"
|
|||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: #2C3E50;">Konfirmasi Izin Melebihi Batas</h3>
|
||||
<h3 style="margin: 0; color: #2C3E50;">⚠️ Konfirmasi Izin Melebihi Batas</h3>
|
||||
</div>
|
||||
<div style="padding: 15px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; margin-bottom: 15px;">
|
||||
<i class="fas fa-exclamation-triangle" style="font-size: 2rem; color: #856404; margin-bottom: 10px;"></i>
|
||||
<h4 style="margin: 10px 0; color: #856404;">Peringatan!</h4>
|
||||
<p id="overLimitMessage" style="margin: 0; color: #856404;"></p>
|
||||
</div>
|
||||
<p>Apakah Anda yakin ingin melanjutkan pengajuan izin ini?</p>
|
||||
<p style="margin: 15px 0;">Izin tetap bisa diproses, tetapi santri ini akan <strong>melebihi kuota maksimal</strong>.</p>
|
||||
<p style="margin: 15px 0; color: #7F8C8D; font-size: 0.9rem;">Apakah Anda yakin ingin melanjutkan pengajuan izin ini?</p>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('overLimitModal')">Batal</button>
|
||||
<button type="button" class="btn btn-warning" id="confirmOverLimit">
|
||||
<i class="fas fa-check"></i> Lanjutkan Tetap
|
||||
<button type="button" class="btn btn-warning" id="confirmOverLimit" style="background: #ff9800; border-color: #ff9800;">
|
||||
<i class="fas fa-check"></i> Ya, Lanjutkan Tetap
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -163,6 +196,7 @@ class="form-control"
|
|||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 500px; width: 90%; margin: auto; }
|
||||
.modal-content { max-height: 90vh; overflow-y: auto; }
|
||||
.badge { display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem; font-weight: 600; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
|
@ -182,46 +216,82 @@ class="form-control"
|
|||
|
||||
const infoDiv = document.getElementById('santriInfo');
|
||||
infoDiv.style.display = 'block';
|
||||
infoDiv.innerHTML = '<div style="text-align: center;"><i class="fas fa-spinner fa-spin"></i> Memuat data santri...</div>';
|
||||
infoDiv.innerHTML = '<div style="text-align: center; padding: 20px;"><i class="fas fa-spinner fa-spin"></i> Memuat data santri...</div>';
|
||||
|
||||
fetch(`/admin/api/kepulangan/santri/${santriId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
currentSantriData = data;
|
||||
updateSantriInfo(data);
|
||||
calculateDurasi();
|
||||
if (data.success) {
|
||||
currentSantriData = data;
|
||||
updateSantriInfo(data);
|
||||
calculateDurasi();
|
||||
} else {
|
||||
infoDiv.innerHTML = `<div class="alert alert-danger">${data.message}</div>`;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
infoDiv.innerHTML = `<div style="padding: 15px; background: #ffe8ea; border: 1px solid #ffd5d8; border-radius: 6px; color: #7C2D35;">Error loading santri data: ${error.message}</div>`;
|
||||
infoDiv.innerHTML = `<div class="alert alert-danger">Error: ${error.message}</div>`;
|
||||
});
|
||||
});
|
||||
|
||||
function updateSantriInfo(data) {
|
||||
const santri = data.santri;
|
||||
const penggunaan = data.penggunaan_izin;
|
||||
const kuota = data.penggunaan_izin;
|
||||
|
||||
const totalColor = penggunaan.total_hari > 8 ? '#ffc107' : '#81C6E8';
|
||||
const sisaColor = penggunaan.sisa_kuota <= 3 ? '#dc3545' : '#6FBA9D';
|
||||
// Tentukan warna badge berdasarkan status
|
||||
let badgeColor = '#28a745'; // Hijau (aman)
|
||||
let badgeTextColor = 'white';
|
||||
if (kuota.status === 'hampir_habis') {
|
||||
badgeColor = '#ffc107'; // Kuning
|
||||
badgeTextColor = '#000';
|
||||
} else if (kuota.status === 'melebihi') {
|
||||
badgeColor = '#dc3545'; // Merah
|
||||
}
|
||||
|
||||
document.getElementById('santriInfo').innerHTML = `
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">Informasi Santri</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Nama:</strong> ${santri.nama_lengkap}</p>
|
||||
<p style="margin: 5px 0;"><strong>Kelas:</strong> ${santri.kelas}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Total Hari Izin Tahun Ini:</strong> <span style="display: inline-block; background: ${totalColor}; color: ${penggunaan.total_hari > 8 ? '#000' : 'white'}; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">${penggunaan.total_hari} hari</span></p>
|
||||
<p style="margin: 5px 0;"><strong>Sisa Kuota:</strong> <span style="display: inline-block; background: ${sisaColor}; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">${penggunaan.sisa_kuota} hari</span></p>
|
||||
</div>
|
||||
</div>
|
||||
${penggunaan.over_limit ? `
|
||||
<div style="margin-top: 15px; padding: 12px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Peringatan:</strong> Santri ini sudah melebihi batas 12 hari per tahun!
|
||||
</div>
|
||||
` : ''}
|
||||
`;
|
||||
// Update info santri
|
||||
document.getElementById('santriNama').textContent = santri.nama_lengkap;
|
||||
document.getElementById('santriKelas').textContent = santri.kelas;
|
||||
document.getElementById('santriPeriode').textContent = kuota.periode_mulai + ' - ' + kuota.periode_akhir;
|
||||
document.getElementById('kuotaMaksimal').textContent = kuota.kuota_maksimal + ' hari';
|
||||
|
||||
const totalTerpakaiSpan = document.getElementById('totalTerpakai');
|
||||
totalTerpakaiSpan.textContent = kuota.total_terpakai + ' hari';
|
||||
totalTerpakaiSpan.style.background = badgeColor;
|
||||
totalTerpakaiSpan.style.color = badgeTextColor;
|
||||
|
||||
const sisaKuotaSpan = document.getElementById('sisaKuota');
|
||||
sisaKuotaSpan.textContent = kuota.sisa_kuota + ' hari';
|
||||
sisaKuotaSpan.style.background = badgeColor;
|
||||
sisaKuotaSpan.style.color = badgeTextColor;
|
||||
|
||||
// Update progress bar
|
||||
const progressBar = document.getElementById('progressBar');
|
||||
const progressText = document.getElementById('progressText');
|
||||
progressBar.style.width = Math.min(100, kuota.persentase) + '%';
|
||||
progressBar.textContent = kuota.persentase + '%';
|
||||
progressText.textContent = kuota.persentase + '% dari kuota terpakai';
|
||||
|
||||
// Ubah warna progress bar
|
||||
if (kuota.persentase >= 100) {
|
||||
progressBar.style.background = '#dc3545'; // Merah
|
||||
} else if (kuota.persentase >= 80) {
|
||||
progressBar.style.background = '#ffc107'; // Kuning
|
||||
} else {
|
||||
progressBar.style.background = '#28a745'; // Hijau
|
||||
}
|
||||
|
||||
// Tampilkan warning jika over limit
|
||||
const warningDiv = document.getElementById('warningOverLimit');
|
||||
const warningText = document.getElementById('warningText');
|
||||
if (kuota.status === 'melebihi') {
|
||||
warningDiv.style.display = 'block';
|
||||
warningText.textContent = `Santri ini sudah melebihi kuota ${kuota.kuota_maksimal} hari per tahun! Total terpakai: ${kuota.total_terpakai} hari.`;
|
||||
} else {
|
||||
warningDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
// Restore full HTML structure
|
||||
document.getElementById('santriInfo').style.display = 'block';
|
||||
}
|
||||
|
||||
// Calculate durasi when dates change
|
||||
|
|
@ -246,57 +316,67 @@ function calculateDurasi() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Hitung durasi (termasuk hari pertama)
|
||||
const diffTime = Math.abs(endDate - startDate);
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
|
||||
|
||||
durasiInfoDiv.style.display = 'block';
|
||||
|
||||
// Update durasi
|
||||
document.getElementById('durasiHari').textContent = diffDays;
|
||||
|
||||
let totalSetelah = diffDays;
|
||||
let sisaSetelah = 12 - diffDays;
|
||||
let showWarning = false;
|
||||
let warningMessage = '';
|
||||
|
||||
if (currentSantriData) {
|
||||
const currentUsage = currentSantriData.penggunaan_izin.total_hari;
|
||||
totalSetelah = currentUsage + diffDays;
|
||||
sisaSetelah = 12 - totalSetelah;
|
||||
const currentUsage = currentSantriData.penggunaan_izin.total_terpakai;
|
||||
const kuotaMaks = currentSantriData.penggunaan_izin.kuota_maksimal;
|
||||
|
||||
if (totalSetelah > 12) {
|
||||
totalSetelah = currentUsage + diffDays;
|
||||
sisaSetelah = kuotaMaks - totalSetelah;
|
||||
|
||||
// Update nilai
|
||||
document.getElementById('totalSetelahIzin').textContent = totalSetelah;
|
||||
document.getElementById('sisaKuotaSetelah').textContent = Math.max(0, sisaSetelah);
|
||||
|
||||
// Ubah warna berdasarkan status
|
||||
const totalSetelahEl = document.getElementById('totalSetelahIzin');
|
||||
const sisaSetelahEl = document.getElementById('sisaKuotaSetelah');
|
||||
|
||||
if (totalSetelah > kuotaMaks) {
|
||||
totalSetelahEl.style.color = '#dc3545';
|
||||
sisaSetelahEl.style.color = '#dc3545';
|
||||
showWarning = true;
|
||||
warningMessage = `Izin ini akan melebihi batas 12 hari per tahun (total: ${totalSetelah} hari)`;
|
||||
warningMessage = `Izin ini akan melebihi batas ${kuotaMaks} hari per tahun (Total setelah izin: ${totalSetelah} hari, Kelebihan: ${totalSetelah - kuotaMaks} hari)`;
|
||||
isOverLimit = true;
|
||||
} else if (totalSetelah >= kuotaMaks * 0.8) {
|
||||
totalSetelahEl.style.color = '#ff9800';
|
||||
sisaSetelahEl.style.color = '#ff9800';
|
||||
showWarning = true;
|
||||
warningMessage = `Perhatian: Kuota hampir habis! Sisa kuota setelah izin ini hanya ${sisaSetelah} hari.`;
|
||||
isOverLimit = false;
|
||||
} else {
|
||||
totalSetelahEl.style.color = '#2196f3';
|
||||
sisaSetelahEl.style.color = '#28a745';
|
||||
showWarning = false;
|
||||
isOverLimit = false;
|
||||
}
|
||||
}
|
||||
|
||||
const durasiColor = diffDays > 7 ? '#ffc107' : '#007bff';
|
||||
const totalColor = totalSetelah > 12 ? '#dc3545' : '#6c757d';
|
||||
const sisaColor = sisaSetelah < 0 ? '#dc3545' : sisaSetelah <= 3 ? '#ffc107' : '#6FBA9D';
|
||||
|
||||
durasiInfoDiv.innerHTML = `
|
||||
<h4 style="margin-top: 0; color: #2C3E50;">Informasi Durasi Izin</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Durasi Izin:</strong> <span style="display: inline-block; background: ${durasiColor}; color: ${diffDays > 7 ? '#000' : 'white'}; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">${diffDays} hari</span></p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Total Setelah Izin:</strong> <span style="display: inline-block; background: ${totalColor}; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">${totalSetelah} hari</span></p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 5px 0;"><strong>Sisa Kuota Setelah Izin:</strong> <span style="display: inline-block; background: ${sisaColor}; color: ${sisaSetelah <= 3 && sisaSetelah >= 0 ? '#000' : 'white'}; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">${Math.max(0, sisaSetelah)} hari</span></p>
|
||||
</div>
|
||||
</div>
|
||||
${showWarning ? `
|
||||
<div style="margin-top: 15px; padding: 12px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
${warningMessage}
|
||||
</div>
|
||||
` : ''}
|
||||
`;
|
||||
// Tampilkan warning durasi
|
||||
const warningDiv = document.getElementById('warningDurasi');
|
||||
const warningMessageEl = document.getElementById('warningDurasiMessage');
|
||||
if (showWarning) {
|
||||
warningDiv.style.display = 'block';
|
||||
warningMessageEl.textContent = warningMessage;
|
||||
} else {
|
||||
warningDiv.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Character counter for alasan
|
||||
// Character counter
|
||||
document.getElementById('alasan').addEventListener('input', function() {
|
||||
const current = this.value.length;
|
||||
const counter = document.getElementById('charCount');
|
||||
|
|
@ -316,8 +396,8 @@ function calculateDurasi() {
|
|||
if (isOverLimit) {
|
||||
e.preventDefault();
|
||||
|
||||
const warningDiv = document.querySelector('#durasiInfo div[style*="background: #fff3cd"]');
|
||||
const message = warningDiv ? warningDiv.textContent.trim() : 'Izin ini melebihi batas 12 hari per tahun';
|
||||
const warningMessageEl = document.getElementById('warningDurasiMessage');
|
||||
const message = warningMessageEl ? warningMessageEl.textContent : 'Izin ini akan melebihi batas kuota per tahun';
|
||||
document.getElementById('overLimitMessage').textContent = message;
|
||||
|
||||
document.getElementById('overLimitModal').style.display = 'flex';
|
||||
|
|
|
|||
|
|
@ -9,6 +9,33 @@
|
|||
<h2><i class="fas fa-home"></i> Data Kepulangan Santri</h2>
|
||||
</div>
|
||||
|
||||
{{-- Info Periode Kuota --}}
|
||||
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 12px; margin-bottom: 20px;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; align-items: center;">
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📅 Periode Kuota</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">
|
||||
{{ $settings->periode_mulai->format('d M Y') }} - {{ $settings->periode_akhir->format('d M Y') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📊 Kuota Maksimal</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">{{ $settings->kuota_maksimal }} Hari / Tahun</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">🔄 Terakhir Reset</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">
|
||||
{{ $settings->terakhir_reset ? $settings->terakhir_reset->format('d M Y') : 'Belum Pernah' }}
|
||||
</p>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<a href="{{ route('admin.kepulangan.settings') }}" class="btn btn-light" style="background: white; color: #667eea; font-weight: 600;">
|
||||
<i class="fas fa-cog"></i> Kelola Pengaturan
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Dashboard Cards --}}
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
|
|
@ -27,9 +54,14 @@
|
|||
<i class="fas fa-home card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-danger">
|
||||
<h3>Over Limit</h3>
|
||||
<h3>Over Limit (>{{ $settings->kuota_maksimal }} Hari)</h3>
|
||||
<div class="card-value">{{ $stats['over_limit_santri'] }}</div>
|
||||
<i class="fas fa-exclamation-triangle card-icon"></i>
|
||||
@if($stats['over_limit_santri'] > 0)
|
||||
<a href="{{ route('admin.kepulangan.over-limit') }}" style="font-size: 0.85rem; color: #dc3545; text-decoration: underline; margin-top: 5px; display: block;">
|
||||
Lihat Detail
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -64,7 +96,7 @@
|
|||
<input type="text"
|
||||
name="search"
|
||||
class="form-control"
|
||||
placeholder="Nama, ID, atau alasan..."
|
||||
placeholder="Cari nama, ID, atau alasan..."
|
||||
value="{{ request('search') }}"
|
||||
id="searchInput">
|
||||
</div>
|
||||
|
|
@ -122,6 +154,7 @@ class="form-control"
|
|||
<th>Tanggal Pulang</th>
|
||||
<th>Tanggal Kembali</th>
|
||||
<th>Durasi</th>
|
||||
<th>Total Kuota Terpakai</th>
|
||||
<th>Alasan</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
|
|
@ -129,12 +162,16 @@ class="form-control"
|
|||
</thead>
|
||||
<tbody>
|
||||
@forelse($kepulangan as $item)
|
||||
<tr style="{{ isset($santriOverLimit[$item->id_santri]) ? 'background-color: #fff3cd;' : '' }}">
|
||||
@php
|
||||
$isOverLimit = isset($santriOverLimit[$item->id_santri]);
|
||||
$totalHariTerpakai = $isOverLimit ? $santriOverLimit[$item->id_santri] : 0;
|
||||
@endphp
|
||||
<tr style="{{ $isOverLimit ? 'background-color: rgba(220, 53, 69, 0.1); border-left: 4px solid #dc3545;' : '' }}">
|
||||
<td>
|
||||
<strong>{{ $item->id_kepulangan }}</strong>
|
||||
@if(isset($santriOverLimit[$item->id_santri]))
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.75rem; margin-left: 5px;"
|
||||
title="Over Limit: {{ $santriOverLimit[$item->id_santri] }} hari">
|
||||
@if($isOverLimit)
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.75rem; margin-left: 5px; animation: pulse 2s infinite;"
|
||||
title="Over Limit: {{ $totalHariTerpakai }} hari">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
@endif
|
||||
|
|
@ -150,10 +187,31 @@ class="form-control"
|
|||
<td>{{ $item->tanggal_pulang_formatted }}</td>
|
||||
<td>{{ $item->tanggal_kembali_formatted }}</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: {{ $item->durasi_izin_calculated > 7 ? '#ffc107' : '#6c757d' }}; color: {{ $item->durasi_izin_calculated > 7 ? '#000' : '#fff' }}; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">
|
||||
{{ $item->durasi_izin_calculated }} hari
|
||||
<span style="display: inline-block; background: {{ $item->durasi_izin > 7 ? '#ffc107' : '#6c757d' }}; color: {{ $item->durasi_izin > 7 ? '#000' : '#fff' }}; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;">
|
||||
{{ $item->durasi_izin }} hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
@php
|
||||
$kuotaSantri = \App\Models\Kepulangan::getSisaKuotaSantri($item->id_santri);
|
||||
$badgeColor = $kuotaSantri['badge_color'];
|
||||
$badgeColors = [
|
||||
'success' => '#28a745',
|
||||
'warning' => '#ffc107',
|
||||
'danger' => '#dc3545'
|
||||
];
|
||||
$bgColor = $badgeColors[$badgeColor] ?? '#6c757d';
|
||||
$textColor = $badgeColor == 'warning' ? '#000' : '#fff';
|
||||
@endphp
|
||||
<div style="text-align: center;">
|
||||
<span style="display: inline-block; background: {{ $bgColor }}; color: {{ $textColor }}; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;">
|
||||
{{ $kuotaSantri['total_terpakai'] }} / {{ $kuotaSantri['kuota_maksimal'] }} hari
|
||||
</span>
|
||||
<div style="margin-top: 5px; font-size: 0.75rem; color: #7F8C8D;">
|
||||
Sisa: {{ $kuotaSantri['sisa_kuota'] }} hari ({{ $kuotaSantri['persentase'] }}%)
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span style="max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block;" title="{{ $item->alasan }}">
|
||||
{{ $item->alasan }}
|
||||
|
|
@ -169,9 +227,9 @@ class="form-control"
|
|||
{{ $item->status }}
|
||||
</span>
|
||||
@if($item->is_aktif)
|
||||
<br><small style="color: #28a745; font-weight: 600;">Sedang Izin</small>
|
||||
<br><small style="color: #28a745; font-weight: 600;">🏠 Sedang Izin</small>
|
||||
@elseif($item->is_terlambat)
|
||||
<br><small style="color: #dc3545; font-weight: 600;">Terlambat</small>
|
||||
<br><small style="color: #dc3545; font-weight: 600;">⏰ Terlambat</small>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center">
|
||||
|
|
@ -227,7 +285,7 @@ class="btn btn-sm btn-danger"
|
|||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" style="text-align: center; padding: 40px;">
|
||||
<td colspan="9" style="text-align: center; padding: 40px;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; color: #ccc; margin-bottom: 15px;"></i>
|
||||
<p style="color: #7F8C8D;">Tidak ada data kepulangan ditemukan</p>
|
||||
</td>
|
||||
|
|
@ -251,7 +309,7 @@ class="btn btn-sm btn-danger"
|
|||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Modal Approve --}}
|
||||
{{-- Modals (sama seperti sebelumnya) --}}
|
||||
<div class="modal fade" id="approveModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -276,7 +334,6 @@ class="btn btn-sm btn-danger"
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal Reject --}}
|
||||
<div class="modal fade" id="rejectModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -301,7 +358,6 @@ class="btn btn-sm btn-danger"
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal Delete --}}
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -324,12 +380,17 @@ class="btn btn-sm btn-danger"
|
|||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 500px; width: 90%; margin: auto; }
|
||||
.modal-content { max-height: 90vh; overflow-y: auto; }
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let currentActionId = null;
|
||||
|
||||
// Auto submit search with debounce
|
||||
// Auto submit search dengan debounce
|
||||
let searchTimeout;
|
||||
document.getElementById('searchInput')?.addEventListener('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,361 @@
|
|||
{{-- resources/views/admin/kepulangan/over-limit.blade.php --}}
|
||||
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Santri Over Limit Kuota')
|
||||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-exclamation-triangle"></i> Santri Over Limit Kuota</h2>
|
||||
</div>
|
||||
|
||||
{{-- Info Periode --}}
|
||||
<div style="background: linear-gradient(135deg, #ff5252 0%, #f48fb1 100%); color: white; padding: 20px; border-radius: 12px; margin-bottom: 20px;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; align-items: center;">
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">⚠️ Total Santri Over Limit</h4>
|
||||
<p style="margin: 0; font-size: 2rem; font-weight: 700;">{{ $santriList->count() }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📅 Periode Kuota</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">
|
||||
{{ $settings->periode_mulai->format('d M Y') }} - {{ $settings->periode_akhir->format('d M Y') }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📊 Kuota Maksimal</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">{{ $settings->kuota_maksimal }} Hari / Tahun</p>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<a href="{{ route('admin.kepulangan.index') }}" class="btn btn-light" style="background: white; color: #dc3545; font-weight: 600;">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Alert Info --}}
|
||||
<div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #ffc107;">
|
||||
<strong>ℹ️ Informasi:</strong>
|
||||
<p style="margin: 10px 0 0 0;">
|
||||
Berikut adalah daftar santri yang telah melebihi kuota maksimal <strong>{{ $settings->kuota_maksimal }} hari</strong> dalam periode ini.
|
||||
Santri tetap bisa mengajukan izin, namun akan mendapat peringatan visual.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
@if($santriList->count() > 0)
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>ID Santri</th>
|
||||
<th>Nama Santri</th>
|
||||
<th>Kelas</th>
|
||||
<th>Total Hari Terpakai</th>
|
||||
<th>Kuota Maksimal</th>
|
||||
<th>Kelebihan</th>
|
||||
<th>Persentase</th>
|
||||
<th>Jumlah Izin</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($santriList as $index => $santri)
|
||||
@php
|
||||
$kelebihan = $santri->total_hari_izin - $settings->kuota_maksimal;
|
||||
@endphp
|
||||
<tr style="background-color: rgba(220, 53, 69, 0.05);">
|
||||
<td>{{ $index + 1 }}</td>
|
||||
<td><strong>{{ $santri->id_santri }}</strong></td>
|
||||
<td>
|
||||
<div>
|
||||
<strong>{{ $santri->nama_lengkap }}</strong><br>
|
||||
<small style="color: #7F8C8D;">NIS: {{ $santri->nis ?? '-' }}</small>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ $santri->kelas }}</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 6px 12px; border-radius: 6px; font-size: 1rem; font-weight: 700;">
|
||||
{{ $santri->total_hari_izin }} hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span style="color: #7F8C8D;">{{ $settings->kuota_maksimal }} hari</span>
|
||||
</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: #721c24; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem; font-weight: 600;">
|
||||
+{{ $kelebihan }} hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="flex: 1; height: 20px; background: #ffebee; border-radius: 10px; overflow: hidden; position: relative;">
|
||||
<div style="height: 100%; width: {{ min(200, $santri->kuota_info['persentase']) }}%; background: linear-gradient(90deg, #dc3545, #c62828); transition: width 0.3s ease; display: flex; align-items: center; justify-content: center;">
|
||||
<span style="font-size: 0.75rem; font-weight: 600; color: white; z-index: 1;">
|
||||
{{ $santri->kuota_info['persentase'] }}%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">
|
||||
{{ $santri->kepulangan->count() }} kali izin
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div style="display: flex; gap: 5px; flex-wrap: wrap;">
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-primary"
|
||||
onclick="showDetailSantri('{{ $santri->id_santri }}')"
|
||||
title="Detail">
|
||||
<i class="fas fa-eye"></i>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-warning"
|
||||
onclick="resetKuotaSantri('{{ $santri->id_santri }}', '{{ $santri->nama_lengkap }}')"
|
||||
title="Reset Kuota">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Summary Statistics --}}
|
||||
<div style="margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 8px;">
|
||||
<h4 style="margin: 0 0 15px 0; color: #2C3E50;">📊 Ringkasan Statistik</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px;">
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px; border: 2px solid #dc3545;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Total Santri Over Limit</div>
|
||||
<div style="font-size: 2rem; font-weight: 700; color: #dc3545;">{{ $santriList->count() }}</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px; border: 2px solid #ff9800;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Rata-rata Kelebihan</div>
|
||||
<div style="font-size: 2rem; font-weight: 700; color: #ff9800;">
|
||||
{{ round($santriList->avg(function($s) use ($settings) { return $s->total_hari_izin - $settings->kuota_maksimal; }), 1) }} hari
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px; border: 2px solid #f44336;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Tertinggi</div>
|
||||
<div style="font-size: 2rem; font-weight: 700; color: #f44336;">
|
||||
{{ $santriList->max('total_hari_izin') }} hari
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: center; padding: 15px; background: white; border-radius: 8px; border: 2px solid #9c27b0;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Total Kelebihan</div>
|
||||
<div style="font-size: 2rem; font-weight: 700; color: #9c27b0;">
|
||||
{{ $santriList->sum(function($s) use ($settings) { return $s->total_hari_izin - $settings->kuota_maksimal; }) }} hari
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Action Buttons --}}
|
||||
<div style="margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap;">
|
||||
<button type="button" class="btn btn-danger" onclick="showResetSemuaOverLimit()">
|
||||
<i class="fas fa-sync-alt"></i> Reset Semua Santri Over Limit
|
||||
</button>
|
||||
<a href="{{ route('admin.kepulangan.settings') }}" class="btn btn-primary">
|
||||
<i class="fas fa-cog"></i> Pengaturan Kuota
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
<div style="text-align: center; padding: 60px; color: #28a745;">
|
||||
<i class="fas fa-check-circle" style="font-size: 4rem; margin-bottom: 20px; display: block;"></i>
|
||||
<h3 style="margin: 0 0 10px 0;">Tidak Ada Santri Over Limit!</h3>
|
||||
<p style="color: #7F8C8D;">Semua santri masih dalam batas kuota yang ditentukan.</p>
|
||||
<a href="{{ route('admin.kepulangan.index') }}" class="btn btn-primary" style="margin-top: 20px;">
|
||||
<i class="fas fa-arrow-left"></i> Kembali ke Kepulangan
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Modal Detail Santri --}}
|
||||
<div class="modal fade" id="detailSantriModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: #2C3E50;">Detail Riwayat Izin Santri</h3>
|
||||
</div>
|
||||
<div id="detailSantriContent">
|
||||
<div style="text-align: center; padding: 40px;">
|
||||
<i class="fas fa-spinner fa-spin" style="font-size: 2rem;"></i>
|
||||
<p style="margin-top: 10px;">Memuat data...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('detailSantriModal')">Tutup</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal Reset Kuota --}}
|
||||
<div class="modal fade" id="resetKuotaModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
<form id="resetKuotaForm">
|
||||
@csrf
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: #2C3E50;">Reset Kuota Santri</h3>
|
||||
</div>
|
||||
<div style="padding: 15px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; margin-bottom: 15px;">
|
||||
<p style="margin: 0; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Anda akan mereset kuota untuk santri: <strong id="resetSantriName"></strong>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Catatan Reset (Opsional):</label>
|
||||
<textarea name="catatan" class="form-control" rows="2" placeholder="Alasan reset kuota..."></textarea>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('resetKuotaModal')">Batal</button>
|
||||
<button type="submit" class="btn btn-warning"><i class="fas fa-sync-alt"></i> Reset Kuota</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 500px; width: 90%; margin: auto; }
|
||||
.modal-dialog.modal-lg { max-width: 800px; }
|
||||
.modal-content { max-height: 90vh; overflow-y: auto; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let currentResetSantriId = null;
|
||||
|
||||
function showDetailSantri(idSantri) {
|
||||
document.getElementById('detailSantriModal').style.display = 'flex';
|
||||
|
||||
// Load detail via AJAX
|
||||
fetch(`/admin/api/kepulangan/santri/${idSantri}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
const santri = data.santri;
|
||||
const kuota = data.penggunaan_izin;
|
||||
|
||||
document.getElementById('detailSantriContent').innerHTML = `
|
||||
<div style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px;">
|
||||
<h4 style="margin: 0 0 15px 0;">${santri.nama_lengkap}</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D;">ID Santri</div>
|
||||
<div style="font-weight: 600;">${santri.id_santri}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D;">Kelas</div>
|
||||
<div style="font-weight: 600;">${santri.kelas}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D;">Total Terpakai</div>
|
||||
<div style="font-weight: 600; color: #dc3545;">${kuota.total_terpakai} hari</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D;">Persentase</div>
|
||||
<div style="font-weight: 600; color: #dc3545;">${kuota.persentase}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 15px; background: #ffebee; border-radius: 8px;">
|
||||
<p style="margin: 0; color: #c62828;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Over Limit!</strong> Santri ini telah melebihi kuota maksimal ${kuota.kuota_maksimal} hari.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
document.getElementById('detailSantriContent').innerHTML = `
|
||||
<div class="alert alert-danger">${data.message}</div>
|
||||
`;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
document.getElementById('detailSantriContent').innerHTML = `
|
||||
<div class="alert alert-danger">Error: ${error.message}</div>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
function resetKuotaSantri(idSantri, namaSantri) {
|
||||
currentResetSantriId = idSantri;
|
||||
document.getElementById('resetSantriName').textContent = namaSantri;
|
||||
document.getElementById('resetKuotaModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
document.getElementById('resetKuotaForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(this);
|
||||
const submitBtn = this.querySelector('button[type="submit"]');
|
||||
const originalText = submitBtn.innerHTML;
|
||||
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Mereset...';
|
||||
|
||||
fetch(`/admin/kepulangan/reset/santri/${currentResetSantriId}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
closeModal('resetKuotaModal');
|
||||
showAlert('success', data.message);
|
||||
setTimeout(() => window.location.reload(), 1500);
|
||||
} else {
|
||||
showAlert('danger', data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => showAlert('danger', 'Error: ' + error.message))
|
||||
.finally(() => {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
});
|
||||
});
|
||||
|
||||
function showResetSemuaOverLimit() {
|
||||
if (confirm('Apakah Anda yakin ingin mereset kuota SEMUA santri yang over limit ({{ $santriList->count() }} santri)?')) {
|
||||
window.location.href = '{{ route("admin.kepulangan.settings") }}#reset-section';
|
||||
}
|
||||
}
|
||||
|
||||
function closeModal(modalId) {
|
||||
document.getElementById(modalId).style.display = 'none';
|
||||
}
|
||||
|
||||
function showAlert(type, message) {
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = `alert alert-${type}`;
|
||||
alertDiv.innerHTML = `<i class="fas fa-${type === 'success' ? 'check' : 'exclamation'}-circle"></i> ${message}`;
|
||||
const pageHeader = document.querySelector('.page-header');
|
||||
pageHeader.insertAdjacentElement('afterend', alertDiv);
|
||||
setTimeout(() => alertDiv.remove(), 5000);
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal.fade').forEach(modal => modal.style.display = 'none');
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll('.modal.fade').forEach(modal => {
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeModal(this.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
{{-- resources/views/admin/kepulangan/settings.blade.php --}}
|
||||
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengaturan Kuota Kepulangan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-cog"></i> Pengaturan Kuota Kepulangan</h2>
|
||||
</div>
|
||||
|
||||
{{-- Flash Messages --}}
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> {{ session('success') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> {{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Statistik Periode Saat Ini --}}
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
<h3>Total Santri Aktif</h3>
|
||||
<div class="card-value">{{ $totalSantri }}</div>
|
||||
<i class="fas fa-users card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-warning">
|
||||
<h3>Total Izin Periode Ini</h3>
|
||||
<div class="card-value">{{ $totalIzinPeriodeIni }}</div>
|
||||
<i class="fas fa-clipboard-list card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-danger">
|
||||
<h3>Santri Over Limit</h3>
|
||||
<div class="card-value">{{ count($santriOverLimit) }}</div>
|
||||
<i class="fas fa-exclamation-triangle card-icon"></i>
|
||||
@if(count($santriOverLimit) > 0)
|
||||
<a href="{{ route('admin.kepulangan.over-limit') }}" style="font-size: 0.85rem; color: #dc3545; text-decoration: underline; margin-top: 5px; display: block;">
|
||||
Lihat Detail
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="card card-success">
|
||||
<h3>Terakhir Reset</h3>
|
||||
<div class="card-value" style="font-size: 1.2rem;">
|
||||
{{ $settings->terakhir_reset ? $settings->terakhir_reset->format('d M Y') : 'Belum Pernah' }}
|
||||
</div>
|
||||
<i class="fas fa-history card-icon"></i>
|
||||
@if($settings->reset_by)
|
||||
<small style="display: block; margin-top: 5px;">oleh {{ $settings->reset_by }}</small>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px;">
|
||||
{{-- Settings Form --}}
|
||||
<div class="content-box">
|
||||
<h3 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #6FBA9D; padding-bottom: 10px;">
|
||||
<i class="fas fa-sliders-h"></i> Pengaturan Kuota
|
||||
</h3>
|
||||
|
||||
<form action="{{ route('admin.kepulangan.settings.update') }}" method="POST">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="form-group">
|
||||
<label for="kuota_maksimal">
|
||||
<i class="fas fa-calculator"></i> Kuota Maksimal (Hari/Tahun)
|
||||
<span style="color: #dc3545;">*</span>
|
||||
</label>
|
||||
<input type="number"
|
||||
name="kuota_maksimal"
|
||||
id="kuota_maksimal"
|
||||
class="form-control"
|
||||
value="{{ old('kuota_maksimal', $settings->kuota_maksimal) }}"
|
||||
min="1"
|
||||
max="365"
|
||||
required>
|
||||
<small style="color: #7F8C8D; display: block; margin-top: 5px;">
|
||||
Maksimal hari izin yang diperbolehkan per tahun (1-365 hari)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="periode_mulai">
|
||||
<i class="fas fa-calendar-alt"></i> Tanggal Mulai Periode
|
||||
<span style="color: #dc3545;">*</span>
|
||||
</label>
|
||||
<input type="date"
|
||||
name="periode_mulai"
|
||||
id="periode_mulai"
|
||||
class="form-control"
|
||||
value="{{ old('periode_mulai', $settings->periode_mulai->format('Y-m-d')) }}"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="periode_akhir">
|
||||
<i class="fas fa-calendar-check"></i> Tanggal Akhir Periode
|
||||
<span style="color: #dc3545;">*</span>
|
||||
</label>
|
||||
<input type="date"
|
||||
name="periode_akhir"
|
||||
id="periode_akhir"
|
||||
class="form-control"
|
||||
value="{{ old('periode_akhir', $settings->periode_akhir->format('Y-m-d')) }}"
|
||||
required>
|
||||
</div>
|
||||
|
||||
<div style="background: #E8F7F2; padding: 15px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #6FBA9D;">
|
||||
<strong>ℹ️ Informasi:</strong>
|
||||
<ul style="margin: 10px 0 0 20px; padding: 0;">
|
||||
<li>Periode ini menentukan rentang waktu perhitungan kuota</li>
|
||||
<li>Perubahan periode akan mempengaruhi perhitungan kuota santri</li>
|
||||
<li>Gunakan fitur reset jika ingin memulai periode baru</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Simpan Pengaturan
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- Reset Actions --}}
|
||||
<div class="content-box">
|
||||
<h3 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #FF8B94; padding-bottom: 10px;">
|
||||
<i class="fas fa-sync-alt"></i> Reset Kuota
|
||||
</h3>
|
||||
|
||||
<div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-bottom: 20px; border-left: 4px solid #ffc107;">
|
||||
<strong>⚠️ PERHATIAN:</strong>
|
||||
<p style="margin: 10px 0 0 0;">
|
||||
Reset kuota akan mengubah status semua izin yang "Disetujui" dalam periode saat ini menjadi "Selesai".
|
||||
Ini akan mereset perhitungan kuota untuk memulai periode baru.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- Reset Semua Santri --}}
|
||||
<div style="background: #ffebee; padding: 20px; border-radius: 8px; border: 2px solid #dc3545; margin-bottom: 20px;">
|
||||
<h4 style="margin: 0 0 10px 0; color: #dc3545;">
|
||||
<i class="fas fa-users"></i> Reset Kuota Semua Santri
|
||||
</h4>
|
||||
<p style="color: #7F8C8D; font-size: 0.9rem; margin-bottom: 15px;">
|
||||
Mereset kuota untuk {{ $totalSantri }} santri aktif. Gunakan di awal tahun ajaran atau periode baru.
|
||||
</p>
|
||||
|
||||
<form id="resetSemuaForm">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="catatan_reset_semua">Catatan Reset (Opsional):</label>
|
||||
<textarea name="catatan"
|
||||
id="catatan_reset_semua"
|
||||
class="form-control"
|
||||
rows="2"
|
||||
placeholder="Contoh: Reset untuk tahun ajaran 2025/2026"></textarea>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="display: flex; align-items: center; cursor: pointer;">
|
||||
<input type="checkbox" name="konfirmasi" id="konfirmasi_reset_semua" required style="margin-right: 10px; width: 18px; height: 18px;">
|
||||
<span>Saya memahami bahwa tindakan ini akan mereset kuota untuk <strong>SEMUA santri</strong></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button type="button" onclick="confirmResetSemua()" class="btn btn-danger" style="width: 100%;">
|
||||
<i class="fas fa-sync-alt"></i> Reset Kuota Semua Santri
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- Info Tambahan --}}
|
||||
<div style="background: #e3f2fd; padding: 15px; border-radius: 8px; border-left: 4px solid #2196f3;">
|
||||
<strong>💡 Tips:</strong>
|
||||
<ul style="margin: 10px 0 0 20px; padding: 0; font-size: 0.9rem;">
|
||||
<li>Reset individual dapat dilakukan dari halaman detail santri</li>
|
||||
<li>Reset massal sebaiknya dilakukan di akhir periode</li>
|
||||
<li>Semua aktivitas reset tercatat dalam log history</li>
|
||||
<li>Data izin lama tetap tersimpan untuk arsip</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- History Reset Logs --}}
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h3 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #6FBA9D; padding-bottom: 10px;">
|
||||
<i class="fas fa-history"></i> History Reset Kuota
|
||||
</h3>
|
||||
|
||||
@if($resetLogs->count() > 0)
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tanggal Reset</th>
|
||||
<th>Jenis Reset</th>
|
||||
<th>Santri</th>
|
||||
<th>Total Hari Direset</th>
|
||||
<th>Periode</th>
|
||||
<th>Kuota Tahunan</th>
|
||||
<th>Reset By</th>
|
||||
<th>Catatan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($resetLogs as $log)
|
||||
<tr>
|
||||
<td>{{ \Carbon\Carbon::parse($log->created_at)->format('d M Y H:i') }}</td>
|
||||
<td>
|
||||
<span style="display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;
|
||||
{{ $log->jenis_reset == 'massal' ? 'background: #dc3545; color: white;' : 'background: #ffc107; color: #000;' }}">
|
||||
{{ $log->jenis_reset == 'massal' ? '👥 Massal' : '👤 Individual' }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
@if($log->id_santri)
|
||||
<strong>{{ $log->nama_lengkap ?? $log->id_santri }}</strong><br>
|
||||
<small style="color: #7F8C8D;">{{ $log->id_santri }}</small>
|
||||
@else
|
||||
<span style="color: #7F8C8D;">Semua Santri</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;">
|
||||
{{ $log->total_hari_sebelum_reset }} hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<small>
|
||||
{{ \Carbon\Carbon::parse($log->periode_mulai)->format('d M Y') }} -
|
||||
{{ \Carbon\Carbon::parse($log->periode_akhir)->format('d M Y') }}
|
||||
</small>
|
||||
</td>
|
||||
<td>{{ $log->kuota_tahunan }} hari</td>
|
||||
<td>{{ $log->reset_by }}</td>
|
||||
<td>
|
||||
<span style="max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block;"
|
||||
title="{{ $log->catatan }}">
|
||||
{{ $log->catatan ?? '-' }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<div style="text-align: center; padding: 40px; color: #7F8C8D;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 15px; display: block;"></i>
|
||||
<p>Belum ada history reset kuota</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Modal Konfirmasi Reset Semua --}}
|
||||
<div class="modal fade" id="confirmResetSemuaModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: #dc3545;">
|
||||
<i class="fas fa-exclamation-triangle"></i> KONFIRMASI RESET MASSAL
|
||||
</h3>
|
||||
</div>
|
||||
<div style="padding: 20px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; margin-bottom: 15px;">
|
||||
<h4 style="margin: 0 0 10px 0; color: #856404;">⚠️ PERINGATAN PENTING!</h4>
|
||||
<p style="margin: 0; color: #856404;">
|
||||
Anda akan mereset kuota untuk <strong>{{ $totalSantri }} santri aktif</strong>.
|
||||
Semua izin yang berstatus "Disetujui" akan diubah menjadi "Selesai".
|
||||
</p>
|
||||
</div>
|
||||
<div style="background: #e3f2fd; padding: 15px; border-radius: 6px; margin-bottom: 20px;">
|
||||
<p style="margin: 0; font-size: 0.9rem;">
|
||||
<strong>Yang akan terjadi:</strong>
|
||||
</p>
|
||||
<ul style="margin: 10px 0 0 20px; padding: 0; font-size: 0.9rem;">
|
||||
<li>Semua perhitungan kuota akan direset ke 0</li>
|
||||
<li>Status izin "Disetujui" → "Selesai"</li>
|
||||
<li>Data arsip tetap tersimpan</li>
|
||||
<li>Aktivitas tercatat dalam log</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p style="margin: 15px 0; font-weight: 600; color: #2C3E50;">
|
||||
Ketik "<span style="color: #dc3545;">RESET SEMUA</span>" untuk melanjutkan:
|
||||
</p>
|
||||
<input type="text"
|
||||
id="confirmationText"
|
||||
class="form-control"
|
||||
placeholder="Ketik: RESET SEMUA"
|
||||
style="margin-bottom: 20px;">
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('confirmResetSemuaModal')">Batal</button>
|
||||
<button type="button" class="btn btn-danger" id="executeResetSemuaBtn" disabled>
|
||||
<i class="fas fa-sync-alt"></i> Ya, Reset Semua Kuota
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 600px; width: 90%; margin: auto; }
|
||||
.modal-content { max-height: 90vh; overflow-y: auto; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
div[style*="grid-template-columns: 1fr 1fr"] {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Validate confirmation text
|
||||
document.getElementById('confirmationText')?.addEventListener('input', function() {
|
||||
const btn = document.getElementById('executeResetSemuaBtn');
|
||||
if (this.value.trim().toUpperCase() === 'RESET SEMUA') {
|
||||
btn.disabled = false;
|
||||
btn.style.opacity = '1';
|
||||
} else {
|
||||
btn.disabled = true;
|
||||
btn.style.opacity = '0.5';
|
||||
}
|
||||
});
|
||||
|
||||
// Show confirmation modal
|
||||
function confirmResetSemua() {
|
||||
const checkbox = document.getElementById('konfirmasi_reset_semua');
|
||||
if (!checkbox.checked) {
|
||||
alert('Anda harus mencentang konfirmasi terlebih dahulu!');
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('confirmResetSemuaModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
// Execute reset semua
|
||||
document.getElementById('executeResetSemuaBtn')?.addEventListener('click', function() {
|
||||
const btn = this;
|
||||
const originalText = btn.innerHTML;
|
||||
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Memproses Reset...';
|
||||
|
||||
const formData = new FormData(document.getElementById('resetSemuaForm'));
|
||||
|
||||
fetch('{{ route("admin.kepulangan.reset.semua") }}', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
closeModal('confirmResetSemuaModal');
|
||||
showAlert('success', data.message);
|
||||
setTimeout(() => window.location.reload(), 2000);
|
||||
} else {
|
||||
showAlert('danger', data.message || 'Terjadi kesalahan saat reset');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
showAlert('danger', 'Error: ' + error.message);
|
||||
})
|
||||
.finally(() => {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalText;
|
||||
});
|
||||
});
|
||||
|
||||
// Helper functions
|
||||
function closeModal(modalId) {
|
||||
document.getElementById(modalId).style.display = 'none';
|
||||
// Reset confirmation text
|
||||
const confirmInput = document.getElementById('confirmationText');
|
||||
if (confirmInput) confirmInput.value = '';
|
||||
}
|
||||
|
||||
function showAlert(type, message) {
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = `alert alert-${type}`;
|
||||
alertDiv.innerHTML = `<i class="fas fa-${type === 'success' ? 'check' : 'exclamation'}-circle"></i> ${message}`;
|
||||
|
||||
const pageHeader = document.querySelector('.page-header');
|
||||
pageHeader.insertAdjacentElement('afterend', alertDiv);
|
||||
|
||||
setTimeout(() => alertDiv.remove(), 5000);
|
||||
}
|
||||
|
||||
// Close modals on ESC
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal.fade').forEach(modal => {
|
||||
modal.style.display = 'none';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Close modal on outside click
|
||||
document.querySelectorAll('.modal.fade').forEach(modal => {
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeModal(this.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-set periode akhir when periode mulai changes
|
||||
document.getElementById('periode_mulai')?.addEventListener('change', function() {
|
||||
const mulai = new Date(this.value);
|
||||
const akhir = new Date(mulai);
|
||||
akhir.setFullYear(akhir.getFullYear() + 1);
|
||||
akhir.setDate(akhir.getDate() - 1);
|
||||
|
||||
document.getElementById('periode_akhir').value = akhir.toISOString().split('T')[0];
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
<div class="content-box">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 10px;">
|
||||
<h3 style="margin: 0;">Informasi Kepulangan</h3>
|
||||
<span style="display: inline-block; padding: 6px 14px; border-radius: 6px; font-size: 1rem; font-weight: 600;
|
||||
<span style="display: inline-block; padding: 8px 16px; border-radius: 6px; font-size: 1rem; font-weight: 600;
|
||||
@if($kepulangan->status == 'Menunggu') background: #ffc107; color: #000;
|
||||
@elseif($kepulangan->status == 'Disetujui') background: #28a745; color: white;
|
||||
@elseif($kepulangan->status == 'Ditolak') background: #dc3545; color: white;
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Kepulangan:</th>
|
||||
<td>{{ $kepulangan->id_kepulangan }}</td>
|
||||
<td><strong>{{ $kepulangan->id_kepulangan }}</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tanggal Pengajuan:</th>
|
||||
|
|
@ -57,8 +57,8 @@
|
|||
<tr>
|
||||
<th>Durasi Izin:</th>
|
||||
<td>
|
||||
<span style="display: inline-block; background: {{ $kepulangan->durasi_izin_calculated > 7 ? '#ffc107' : '#007bff' }}; color: {{ $kepulangan->durasi_izin_calculated > 7 ? '#000' : 'white' }}; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem;">
|
||||
{{ $kepulangan->durasi_izin_calculated }} hari
|
||||
<span style="display: inline-block; background: {{ $kepulangan->durasi_izin > 7 ? '#ffc107' : '#007bff' }}; color: {{ $kepulangan->durasi_izin > 7 ? '#000' : 'white' }}; padding: 6px 12px; border-radius: 6px; font-size: 1rem; font-weight: 600;">
|
||||
{{ $kepulangan->durasi_izin }} hari
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -66,13 +66,21 @@
|
|||
<th>Status Kepulangan:</th>
|
||||
<td>
|
||||
@if($kepulangan->is_aktif)
|
||||
<span style="display: inline-block; background: #28a745; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Sedang Izin</span>
|
||||
<span style="display: inline-block; background: #28a745; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem;">
|
||||
🏠 Sedang Izin
|
||||
</span>
|
||||
@elseif($kepulangan->is_terlambat)
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Terlambat Kembali</span>
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem;">
|
||||
⏰ Terlambat Kembali
|
||||
</span>
|
||||
@elseif($kepulangan->status == 'Selesai')
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Sudah Selesai</span>
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem;">
|
||||
✅ Sudah Selesai
|
||||
</span>
|
||||
@else
|
||||
<span style="display: inline-block; background: #81C6E8; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Belum Dimulai</span>
|
||||
<span style="display: inline-block; background: #81C6E8; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.9rem;">
|
||||
📅 Belum Dimulai
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -82,11 +90,11 @@
|
|||
</tr>
|
||||
@if($kepulangan->approved_by)
|
||||
<tr>
|
||||
<th>Disetujui Oleh:</th>
|
||||
<th>Diproses Oleh:</th>
|
||||
<td>{{ $kepulangan->approved_by }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tanggal Persetujuan:</th>
|
||||
<th>Tanggal Diproses:</th>
|
||||
<td>{{ $kepulangan->approved_at_formatted }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
|
@ -163,56 +171,83 @@ class="btn btn-primary" target="_blank">
|
|||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Statistik Penggunaan Izin --}}
|
||||
{{-- Statistik Kuota Santri --}}
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #6FBA9D; padding-bottom: 10px;">
|
||||
<i class="fas fa-chart-bar"></i> Statistik Izin {{ $kepulangan->tanggal_pulang->year }}
|
||||
<i class="fas fa-chart-pie"></i> Kuota Izin Periode Ini
|
||||
</h4>
|
||||
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px; text-align: center;">
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px;">
|
||||
<div>
|
||||
<h3 style="margin: 0; color: #007bff;">{{ $detailIzin['total_hari'] }}</h3>
|
||||
<small style="color: #7F8C8D;">Total Hari</small>
|
||||
</div>
|
||||
<div>
|
||||
<h3 style="margin: 0; color: #81C6E8;">{{ $detailIzin['total_izin'] }}</h3>
|
||||
<small style="color: #7F8C8D;">Total Izin</small>
|
||||
|
||||
<div style="background: linear-gradient(135deg, {{ $kuotaSantri['badge_color'] == 'danger' ? '#ff5252 0%, #f48fb1 100%' : ($kuotaSantri['badge_color'] == 'warning' ? '#ffd54f 0%, #ffb74d 100%' : '#81c784 0%, #66bb6a 100%') }}); padding: 20px; border-radius: 12px; text-align: center; color: white; margin-bottom: 15px;">
|
||||
<div style="font-size: 0.9rem; opacity: 0.9; margin-bottom: 5px;">Total Terpakai</div>
|
||||
<div style="font-size: 3rem; font-weight: 700; line-height: 1;">{{ $kuotaSantri['total_terpakai'] }}</div>
|
||||
<div style="font-size: 1rem; opacity: 0.9;">dari {{ $kuotaSantri['kuota_maksimal'] }} hari</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px;">
|
||||
<div style="text-align: center; padding: 15px; background: #f8f9fa; border-radius: 8px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Sisa Kuota</div>
|
||||
<div style="font-size: 1.8rem; font-weight: 700; color: {{ $kuotaSantri['badge_color'] == 'danger' ? '#dc3545' : ($kuotaSantri['badge_color'] == 'warning' ? '#ff9800' : '#28a745') }};">
|
||||
{{ $kuotaSantri['sisa_kuota'] }}
|
||||
</div>
|
||||
<div style="font-size: 0.8rem; color: #7F8C8D;">hari</div>
|
||||
</div>
|
||||
<hr style="margin: 15px 0; border: none; border-top: 1px solid #dee2e6;">
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||
<div>
|
||||
<h4 style="margin: 0; color: {{ $detailIzin['sisa_kuota'] <= 3 ? '#dc3545' : '#28a745' }};">
|
||||
{{ $detailIzin['sisa_kuota'] }}
|
||||
</h4>
|
||||
<small style="color: #7F8C8D;">Sisa Kuota</small>
|
||||
</div>
|
||||
<div>
|
||||
@if($detailIzin['over_limit'])
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Over Limit</span>
|
||||
@else
|
||||
<span style="display: inline-block; background: #28a745; color: white; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem;">Normal</span>
|
||||
@endif
|
||||
<div style="text-align: center; padding: 15px; background: #f8f9fa; border-radius: 8px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">Persentase</div>
|
||||
<div style="font-size: 1.8rem; font-weight: 700; color: {{ $kuotaSantri['badge_color'] == 'danger' ? '#dc3545' : ($kuotaSantri['badge_color'] == 'warning' ? '#ff9800' : '#28a745') }};">
|
||||
{{ $kuotaSantri['persentase'] }}%
|
||||
</div>
|
||||
<div style="font-size: 0.8rem; color: #7F8C8D;">terpakai</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Progress Bar --}}
|
||||
<div style="margin-top: 15px;">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<label style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px; display: block;">
|
||||
Penggunaan Kuota ({{ $detailIzin['total_hari'] }}/12 hari)
|
||||
Penggunaan Kuota ({{ $kuotaSantri['total_terpakai'] }}/{{ $kuotaSantri['kuota_maksimal'] }} hari)
|
||||
</label>
|
||||
<div style="width: 100%; height: 10px; background: #E0F0EC; border-radius: 5px; overflow: hidden;">
|
||||
<div style="width: {{ min(100, ($detailIzin['total_hari'] / 12) * 100) }}%; height: 100%; background: {{ $detailIzin['over_limit'] ? '#dc3545' : ($detailIzin['total_hari'] > 8 ? '#ffc107' : '#28a745') }}; transition: width 0.3s ease;"></div>
|
||||
<div style="width: 100%; height: 15px; background: #E0F0EC; border-radius: 8px; overflow: hidden;">
|
||||
<div style="width: {{ min(100, $kuotaSantri['persentase']) }}%; height: 100%; background: {{ $kuotaSantri['badge_color'] == 'danger' ? '#dc3545' : ($kuotaSantri['badge_color'] == 'warning' ? '#ffc107' : '#28a745') }}; transition: width 0.3s ease;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($kuotaSantri['status'] == 'melebihi')
|
||||
<div style="padding: 12px; background: #ffebee; border: 1px solid #ffcdd2; border-radius: 6px; color: #c62828; font-size: 0.9rem;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>OVER LIMIT!</strong> Santri ini telah melebihi kuota maksimal.
|
||||
</div>
|
||||
@elseif($kuotaSantri['status'] == 'hampir_habis')
|
||||
<div style="padding: 12px; background: #fff3e0; border: 1px solid #ffe0b2; border-radius: 6px; color: #e65100; font-size: 0.9rem;">
|
||||
<i class="fas fa-exclamation-circle"></i>
|
||||
<strong>Hampir Habis!</strong> Kuota hampir mencapai batas maksimal.
|
||||
</div>
|
||||
@else
|
||||
<div style="padding: 12px; background: #e8f5e9; border: 1px solid #c8e6c9; border-radius: 6px; color: #2e7d32; font-size: 0.9rem;">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<strong>Aman!</strong> Kuota masih dalam batas normal.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-radius: 6px; font-size: 0.85rem; color: #7F8C8D;">
|
||||
<strong>Periode:</strong><br>
|
||||
{{ $kuotaSantri['periode_mulai'] }} - {{ $kuotaSantri['periode_akhir'] }}
|
||||
</div>
|
||||
|
||||
{{-- Reset Individual Button --}}
|
||||
@if($kuotaSantri['total_terpakai'] > 0)
|
||||
<button type="button"
|
||||
class="btn btn-warning"
|
||||
style="width: 100%; margin-top: 15px;"
|
||||
onclick="resetKuotaSantri('{{ $kepulangan->id_santri }}', '{{ $kepulangan->santri->nama_lengkap }}')">
|
||||
<i class="fas fa-sync-alt"></i> Reset Kuota Santri Ini
|
||||
</button>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Riwayat Izin --}}
|
||||
{{-- Riwayat Izin Periode Ini --}}
|
||||
@if(count($detailIzin['details']) > 0)
|
||||
<div class="content-box">
|
||||
<h4 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #6FBA9D; padding-bottom: 10px;">
|
||||
<i class="fas fa-history"></i> Riwayat Izin {{ $kepulangan->tanggal_pulang->year }}
|
||||
<i class="fas fa-history"></i> Riwayat Izin Periode Ini
|
||||
</h4>
|
||||
<div style="position: relative; padding-left: 20px;">
|
||||
@foreach($detailIzin['details'] as $detail)
|
||||
|
|
@ -222,14 +257,19 @@ class="btn btn-primary" target="_blank">
|
|||
<i class="fas fa-star" style="color: #ffc107;"></i>
|
||||
</div>
|
||||
@endif
|
||||
<strong style="color: #2C3E50;">{{ $detail['id'] }}</strong>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-top: 3px;">{{ $detail['tanggal'] }}</div>
|
||||
<div style="font-size: 0.9rem; margin-top: 5px;">
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 2px 6px; border-radius: 3px; font-size: 0.8rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 5px;">
|
||||
<strong style="color: #2C3E50;">{{ $detail['id'] }}</strong>
|
||||
<span style="display: inline-block; background: {{ $detail['status'] == 'Disetujui' ? '#28a745' : '#6c757d' }}; color: white; padding: 2px 6px; border-radius: 3px; font-size: 0.75rem;">
|
||||
{{ $detail['status'] }}
|
||||
</span>
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-bottom: 5px;">{{ $detail['tanggal'] }}</div>
|
||||
<div style="font-size: 0.9rem; margin-bottom: 5px;">
|
||||
<span style="display: inline-block; background: #007bff; color: white; padding: 2px 8px; border-radius: 3px; font-size: 0.8rem; font-weight: 600;">
|
||||
{{ $detail['durasi'] }} hari
|
||||
</span>
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D; margin-top: 5px;">
|
||||
<div style="font-size: 0.85rem; color: #7F8C8D;">
|
||||
{{ \Illuminate\Support\Str::limit($detail['alasan'], 50) }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -244,31 +284,28 @@ class="btn btn-primary" target="_blank">
|
|||
@if($history->count() > 0)
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h4 style="margin-top: 0; color: #2C3E50; border-bottom: 2px solid #6FBA9D; padding-bottom: 10px;">
|
||||
<i class="fas fa-list"></i> Riwayat Kepulangan Lainnya
|
||||
<i class="fas fa-list"></i> Riwayat Kepulangan Lainnya (5 Terakhir)
|
||||
</h4>
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Tanggal Pulang</th>
|
||||
<th>Durasi</th>
|
||||
<th>Status</th>
|
||||
<th>Alasan</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($history as $item)
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ route('admin.kepulangan.show', $item->id_kepulangan) }}" style="color: #6FBA9D; text-decoration: none; font-weight: 600;">
|
||||
{{ $item->id_kepulangan }}
|
||||
</a>
|
||||
</td>
|
||||
<td><strong>{{ $item->id_kepulangan }}</strong></td>
|
||||
<td>{{ $item->tanggal_pulang_formatted }}</td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: #6c757d; color: white; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">
|
||||
{{ $item->durasi_izin_calculated }} hari
|
||||
{{ $item->durasi_izin }} hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
|
|
@ -282,6 +319,12 @@ class="btn btn-primary" target="_blank">
|
|||
</span>
|
||||
</td>
|
||||
<td>{{ \Illuminate\Support\Str::limit($item->alasan, 30) }}</td>
|
||||
<td>
|
||||
<a href="{{ route('admin.kepulangan.show', $item->id_kepulangan) }}"
|
||||
class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
|
@ -290,7 +333,7 @@ class="btn btn-primary" target="_blank">
|
|||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modals (sama seperti di index) --}}
|
||||
{{-- Modals --}}
|
||||
<div class="modal fade" id="approveModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -333,6 +376,33 @@ class="btn btn-primary" target="_blank">
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="resetKuotaModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
<form id="resetKuotaForm">
|
||||
@csrf
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: #2C3E50;">Reset Kuota Santri</h3>
|
||||
</div>
|
||||
<div style="padding: 15px; background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 6px; margin-bottom: 15px;">
|
||||
<p style="margin: 0; color: #856404;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Anda akan mereset kuota untuk santri: <strong id="resetSantriName"></strong>
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Catatan Reset (Opsional):</label>
|
||||
<textarea name="catatan" class="form-control" rows="2" placeholder="Alasan reset kuota..."></textarea>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 20px;">
|
||||
<button type="button" class="btn btn-secondary" onclick="closeModal('resetKuotaModal')">Batal</button>
|
||||
<button type="submit" class="btn btn-warning"><i class="fas fa-sync-alt"></i> Reset Kuota</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 500px; width: 90%; margin: auto; }
|
||||
|
|
@ -343,6 +413,8 @@ class="btn btn-primary" target="_blank">
|
|||
</style>
|
||||
|
||||
<script>
|
||||
let currentResetSantriId = null;
|
||||
|
||||
function approveKepulangan() {
|
||||
document.getElementById('approveModal').style.display = 'flex';
|
||||
}
|
||||
|
|
@ -432,6 +504,43 @@ function completeKepulangan() {
|
|||
}
|
||||
}
|
||||
|
||||
function resetKuotaSantri(idSantri, namaSantri) {
|
||||
currentResetSantriId = idSantri;
|
||||
document.getElementById('resetSantriName').textContent = namaSantri;
|
||||
document.getElementById('resetKuotaModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
document.getElementById('resetKuotaForm').addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(this);
|
||||
const submitBtn = this.querySelector('button[type="submit"]');
|
||||
const originalText = submitBtn.innerHTML;
|
||||
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Mereset...';
|
||||
|
||||
fetch(`/admin/kepulangan/reset/santri/${currentResetSantriId}`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
closeModal('resetKuotaModal');
|
||||
showAlert('success', data.message);
|
||||
setTimeout(() => window.location.reload(), 1500);
|
||||
} else {
|
||||
showAlert('danger', data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => showAlert('danger', 'Error: ' + error.message))
|
||||
.finally(() => {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.innerHTML = originalText;
|
||||
});
|
||||
});
|
||||
|
||||
function closeModal(modalId) {
|
||||
document.getElementById(modalId).style.display = 'none';
|
||||
}
|
||||
|
|
@ -450,5 +559,13 @@ function showAlert(type, message) {
|
|||
document.querySelectorAll('.modal.fade').forEach(modal => modal.style.display = 'none');
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll('.modal.fade').forEach(modal => {
|
||||
modal.addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
closeModal(this.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -12,98 +12,126 @@
|
|||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 20mm;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 2px solid #000;
|
||||
border-bottom: 3px solid #000;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin: 0 auto 10px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 18pt;
|
||||
font-weight: bold;
|
||||
margin: 5px 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.header h2 {
|
||||
font-size: 16pt;
|
||||
margin: 5px 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 10pt;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
margin: 30px 0 20px 0;
|
||||
font-size: 14pt;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.nomor {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
font-size: 12pt;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-bottom: 30px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.content p {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.data-santri {
|
||||
margin: 20px 0;
|
||||
padding-left: 50px;
|
||||
margin: 20px 0 20px 50px;
|
||||
}
|
||||
|
||||
.data-row {
|
||||
display: table;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.data-label {
|
||||
display: table-cell;
|
||||
width: 150px;
|
||||
width: 180px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.data-separator {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.data-value {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.signature-section {
|
||||
margin-top: 50px;
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
.signature-row {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.signature-left, .signature-right {
|
||||
display: table-cell;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.signature-space {
|
||||
height: 80px;
|
||||
margin: 20px 0 10px;
|
||||
}
|
||||
|
||||
.signature-name {
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #000;
|
||||
display: inline-block;
|
||||
min-width: 150px;
|
||||
min-width: 180px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
bottom: 10mm;
|
||||
bottom: 15mm;
|
||||
left: 20mm;
|
||||
right: 20mm;
|
||||
font-size: 8pt;
|
||||
|
|
@ -112,23 +140,81 @@
|
|||
padding-top: 10px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.watermark {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
font-size: 72pt;
|
||||
color: rgba(0, 0, 0, 0.05);
|
||||
font-size: 100pt;
|
||||
color: rgba(0, 0, 0, 0.03);
|
||||
z-index: -1;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-approved {
|
||||
color: green;
|
||||
color: #28a745;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.catatan-box {
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
background-color: #f8f9fa;
|
||||
border: 2px solid #dee2e6;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
margin: 20px 0;
|
||||
padding: 12px;
|
||||
background-color: #fff3cd;
|
||||
border-left: 4px solid #ffc107;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 10px 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body { margin: 0; }
|
||||
.footer { position: fixed; }
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.footer {
|
||||
position: fixed;
|
||||
}
|
||||
.page-break {
|
||||
page-break-after: always;
|
||||
}
|
||||
}
|
||||
|
||||
.tracking-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.tracking-table th,
|
||||
.tracking-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.tracking-table th {
|
||||
background-color: #f0f0f0;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
@ -138,10 +224,13 @@
|
|||
|
||||
{{-- Header --}}
|
||||
<div class="header">
|
||||
{{-- Logo (jika ada) --}}
|
||||
{{-- <img src="{{ asset('images/logo-pesantren.png') }}" alt="Logo" class="logo"> --}}
|
||||
|
||||
<h1>Pondok Pesantren Al-Hikmah</h1>
|
||||
<h2>Yayasan Pendidikan Islam</h2>
|
||||
<p>Jl. Raya Pesantren No. 123, Jakarta Selatan</p>
|
||||
<p>Telp: (021) 123456 | Email: info@alhikmah.ac.id</p>
|
||||
<p>Jl. Raya Pesantren No. 123, Jakarta Selatan 12345</p>
|
||||
<p>Telp: (021) 123456 | Email: info@alhikmah.ac.id | Website: www.alhikmah.ac.id</p>
|
||||
</div>
|
||||
|
||||
{{-- Title --}}
|
||||
|
|
@ -151,7 +240,7 @@
|
|||
|
||||
{{-- Nomor Surat --}}
|
||||
<div class="nomor">
|
||||
Nomor: {{ $kepulangan->id_kepulangan }}/IZIN/{{ $kepulangan->tanggal_pulang->format('m') }}/{{ $kepulangan->tanggal_pulang->year }}
|
||||
Nomor: {{ $kepulangan->id_kepulangan }}/IZIN-PULANG/PP-AH/{{ $kepulangan->tanggal_pulang->format('m') }}/{{ $kepulangan->tanggal_pulang->year }}
|
||||
</div>
|
||||
|
||||
{{-- Content --}}
|
||||
|
|
@ -160,12 +249,12 @@
|
|||
|
||||
<div class="data-santri">
|
||||
<div class="data-row">
|
||||
<div class="data-label">Nama</div>
|
||||
<div class="data-label">Nama Lengkap</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $santri->nama_lengkap }}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">NIS</div>
|
||||
<div class="data-label">Nomor Induk Santri (NIS)</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $santri->nis ?? '-' }}</div>
|
||||
</div>
|
||||
|
|
@ -187,27 +276,32 @@
|
|||
<div class="data-row">
|
||||
<div class="data-label">Alamat</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $santri->alamat_santri ?? $santri->daerah_asal ?? '-' }}</div>
|
||||
<div class="data-value">{{ $santri->alamat_santri ?? $santri->daerah_asal ?? 'Tidak tercatat' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Adalah benar-benar santri aktif di Pondok Pesantren Al-Hikmah dan telah mendapat izin untuk pulang ke rumah dengan keterangan sebagai berikut:</p>
|
||||
|
||||
<div class="data-santri">
|
||||
<div class="data-row">
|
||||
<div class="data-label">Tanggal Pengajuan Izin</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $kepulangan->tanggal_izin->format('d F Y') }}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">Tanggal Pulang</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $kepulangan->tanggal_pulang->format('d F Y') }}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">Tanggal Kembali</div>
|
||||
<div class="data-label">Tanggal Wajib Kembali</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $kepulangan->tanggal_kembali->format('d F Y') }}</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">Durasi Izin</div>
|
||||
<div class="data-separator">:</div>
|
||||
<div class="data-value">{{ $kepulangan->durasi_izin_calculated }} hari</div>
|
||||
<div class="data-value">{{ $kepulangan->durasi_izin }} hari</div>
|
||||
</div>
|
||||
<div class="data-row">
|
||||
<div class="data-label">Alasan Kepulangan</div>
|
||||
|
|
@ -228,15 +322,18 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
<p>Demikian surat izin ini dibuat untuk dapat digunakan sebagaimana mestinya. Santri yang bersangkutan <strong>WAJIB</strong> kembali pada tanggal yang telah ditentukan.</p>
|
||||
<p>Demikian surat izin ini dibuat dengan sebenarnya untuk dapat digunakan sebagaimana mestinya. Santri yang bersangkutan <strong>WAJIB</strong> kembali ke pesantren pada tanggal yang telah ditentukan di atas.</p>
|
||||
|
||||
<p><strong>Catatan Penting:</strong></p>
|
||||
<ul style="margin-left: 30px;">
|
||||
<li>Santri wajib kembali sesuai tanggal yang tertera dalam surat ini</li>
|
||||
<li>Apabila terlambat kembali tanpa pemberitahuan, akan dikenakan sanksi sesuai peraturan pesantren</li>
|
||||
<li>Surat ini harus dibawa dan ditunjukkan kepada petugas jaga saat keluar dan masuk pesantren</li>
|
||||
<li>Orang tua/wali santri bertanggung jawab penuh selama santri berada di rumah</li>
|
||||
</ul>
|
||||
<div class="info-box">
|
||||
<p style="margin: 0;"><strong>⚠️ KETENTUAN PENTING:</strong></p>
|
||||
<ul style="margin: 10px 0 0 0;">
|
||||
<li>Santri wajib kembali sesuai tanggal yang tertera dalam surat ini</li>
|
||||
<li>Apabila terlambat kembali tanpa pemberitahuan yang sah, akan dikenakan sanksi sesuai peraturan pesantren</li>
|
||||
<li>Surat ini harus dibawa dan ditunjukkan kepada petugas jaga saat keluar dan masuk pesantren</li>
|
||||
<li>Orang tua/wali santri bertanggung jawab penuh atas keselamatan santri selama berada di rumah</li>
|
||||
<li>Harap menghubungi pihak pesantren jika terjadi kondisi darurat yang mengharuskan perpanjangan waktu kepulangan</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Signature Section --}}
|
||||
|
|
@ -245,14 +342,13 @@
|
|||
<div class="signature-left">
|
||||
<p>Mengetahui,<br>Wali Santri</p>
|
||||
<div class="signature-space"></div>
|
||||
<div class="signature-name">{{ $santri->nama_orang_tua ?? '........................' }}</div>
|
||||
<div class="signature-name">{{ $santri->nama_orang_tua ?? '( ........................... )' }}</div>
|
||||
</div>
|
||||
<div class="signature-right">
|
||||
<p>Jakarta, {{ $tanggalCetak }}</p>
|
||||
<p>Pengurus Pondok Pesantren</p>
|
||||
<p>Pengurus Pondok Pesantren<br>Bidang Kesiswaan</p>
|
||||
<div class="signature-space"></div>
|
||||
<div class="signature-name">{{ $kepulangan->approved_by ?? 'Admin' }}</div>
|
||||
<p style="margin-top: 5px; font-size: 10pt;">Bidang Kesiswaan</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -263,7 +359,137 @@
|
|||
Dicetak pada: {{ $tanggalCetak }} |
|
||||
ID: {{ $kepulangan->id_kepulangan }} |
|
||||
Status: {{ $kepulangan->status }} |
|
||||
Surat ini sah tanpa tanda tangan basah
|
||||
Surat ini sah tanpa tanda tangan basah (Digital Signature)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- PAGE BREAK untuk halaman kedua (Lembar Tracking) --}}
|
||||
<div class="page-break"></div>
|
||||
|
||||
{{-- Halaman 2: Lembar Tracking & Arsip --}}
|
||||
<div class="header">
|
||||
<h1>Pondok Pesantren Al-Hikmah</h1>
|
||||
<h2>Lembar Tracking Kepulangan Santri</h2>
|
||||
<p style="font-style: italic; color: #666;">(Lembar Arsip Internal - Tidak untuk diserahkan kepada santri)</p>
|
||||
</div>
|
||||
|
||||
<div class="title" style="font-size: 12pt;">
|
||||
Tracking ID: {{ $kepulangan->id_kepulangan }}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="catatan-box">
|
||||
<p style="margin: 0 0 10px 0;"><strong>📋 Data Kepulangan</strong></p>
|
||||
<table style="width: 100%; border-collapse: collapse;">
|
||||
<tr>
|
||||
<td style="padding: 5px; width: 180px;"><strong>ID Kepulangan</strong></td>
|
||||
<td style="padding: 5px;">: {{ $kepulangan->id_kepulangan }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;"><strong>Nama Santri</strong></td>
|
||||
<td style="padding: 5px;">: {{ $santri->nama_lengkap }} ({{ $santri->id_santri }})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;"><strong>Kelas</strong></td>
|
||||
<td style="padding: 5px;">: {{ $santri->kelas }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;"><strong>No. HP Wali</strong></td>
|
||||
<td style="padding: 5px;">: {{ $santri->no_hp_wali ?? '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;"><strong>Periode Izin</strong></td>
|
||||
<td style="padding: 5px;">: {{ $kepulangan->tanggal_pulang_formatted }} s/d {{ $kepulangan->tanggal_kembali_formatted }} ({{ $kepulangan->durasi_izin }} hari)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px; vertical-align: top;"><strong>Alasan</strong></td>
|
||||
<td style="padding: 5px;">: {{ $kepulangan->alasan }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 5px;"><strong>Disetujui Oleh</strong></td>
|
||||
<td style="padding: 5px;">: {{ $kepulangan->approved_by }} - {{ $kepulangan->approved_at_formatted }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 style="margin: 30px 0 15px 0; font-size: 12pt;">📊 Tracking Kepulangan</h3>
|
||||
<table class="tracking-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 25%;">Status</th>
|
||||
<th style="width: 25%;">Tanggal/Waktu</th>
|
||||
<th style="width: 30%;">Keterangan</th>
|
||||
<th style="width: 20%;">Petugas</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Diajukan</td>
|
||||
<td>{{ $kepulangan->tanggal_izin_formatted }}</td>
|
||||
<td>Pengajuan izin kepulangan</td>
|
||||
<td>Santri</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ $kepulangan->status }}</td>
|
||||
<td>{{ $kepulangan->approved_at_formatted }}</td>
|
||||
<td>{{ $kepulangan->status == 'Disetujui' ? 'Izin disetujui dan surat dicetak' : 'Status diubah' }}</td>
|
||||
<td>{{ $kepulangan->approved_by }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Keluar Pesantren</td>
|
||||
<td>_______________________</td>
|
||||
<td>Santri keluar dari pesantren</td>
|
||||
<td>_____________________</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kembali ke Pesantren</td>
|
||||
<td>_______________________</td>
|
||||
<td>Santri kembali ke pesantren</td>
|
||||
<td>_____________________</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 30px; padding: 15px; background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 5px;">
|
||||
<p style="margin: 0 0 10px 0;"><strong>📞 Kontak Darurat:</strong></p>
|
||||
<table style="width: 100%; font-size: 10pt;">
|
||||
<tr>
|
||||
<td style="padding: 3px;"><strong>Pesantren (Kantor)</strong></td>
|
||||
<td style="padding: 3px;">: (021) 123456</td>
|
||||
<td style="padding: 3px;"><strong>Keamanan 24 Jam</strong></td>
|
||||
<td style="padding: 3px;">: (021) 123457</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px;"><strong>Pengurus Putra</strong></td>
|
||||
<td style="padding: 3px;">: 0812-3456-7890</td>
|
||||
<td style="padding: 3px;"><strong>Pengurus Putri</strong></td>
|
||||
<td style="padding: 3px;">: 0812-3456-7891</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 3px;"><strong>Wali Santri</strong></td>
|
||||
<td style="padding: 3px;">: {{ $santri->no_hp_wali ?? 'Belum ada data' }}</td>
|
||||
<td style="padding: 3px;"><strong>Email Pesantren</strong></td>
|
||||
<td style="padding: 3px;">: info@alhikmah.ac.id</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px; padding: 12px; background-color: #fff3cd; border-left: 4px solid #ffc107;">
|
||||
<p style="margin: 0; font-size: 10pt;"><strong>⚠️ Catatan untuk Petugas:</strong></p>
|
||||
<ul style="margin: 5px 0 0 20px; font-size: 10pt;">
|
||||
<li>Pastikan santri membawa surat izin asli saat keluar</li>
|
||||
<li>Catat waktu keluar dan kembali dengan akurat</li>
|
||||
<li>Hubungi wali santri jika santri terlambat kembali lebih dari 2 jam</li>
|
||||
<li>Simpan lembar tracking ini untuk arsip administrasi</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>
|
||||
Lembar Arsip Internal | Dicetak: {{ $tanggalCetak }} |
|
||||
ID: {{ $kepulangan->id_kepulangan }} |
|
||||
Halaman 2 dari 2
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -4,17 +4,10 @@
|
|||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-user-edit"></i> Edit Santri</h2>
|
||||
<h2><i class="fas fa-user-edit"></i> Edit Data Santri</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div style="background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); padding: 15px 20px; border-radius: 8px; margin-bottom: 25px; border-left: 4px solid #6FBA9D;">
|
||||
<p style="margin: 0; color: #2C5F4F;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Sedang mengedit data:</strong> {{ $santri->nama_lengkap }} ({{ $santri->id_santri }})
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<strong><i class="fas fa-exclamation-triangle"></i> Terdapat kesalahan:</strong>
|
||||
|
|
@ -26,6 +19,32 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
@include('admin.santri.form', ['santri' => $santri])
|
||||
{{-- Info Box: Data Santri yang Sedang Diedit --}}
|
||||
<div style="background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); padding: 20px; border-radius: 8px; border-left: 4px solid #81C6E8; margin-bottom: 25px;">
|
||||
<div style="display: flex; align-items: center; gap: 15px;">
|
||||
@if($santri->foto)
|
||||
<img src="{{ asset('storage/' . $santri->foto) }}"
|
||||
alt="Foto {{ $santri->nama_lengkap }}"
|
||||
style="width: 60px; height: 60px; border-radius: 50%; object-fit: cover; border: 3px solid #81C6E8;"
|
||||
loading="lazy">
|
||||
@else
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: #81C6E8; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 1.5rem;">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<p style="margin: 0; color: #2D4A7C; font-size: 0.9rem;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Sedang mengedit data:</strong>
|
||||
</p>
|
||||
<p style="margin: 5px 0 0 0; color: #2D4A7C; font-weight: 600; font-size: 1.1rem;">
|
||||
{{ $santri->nama_lengkap }} ({{ $santri->id_santri }})
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.santri.form')
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
$isEdit = isset($santri);
|
||||
@endphp
|
||||
|
||||
<form action="{{ $isEdit ? route('admin.santri.update', $santri) : route('admin.santri.store') }}" method="POST" class="data-form">
|
||||
<form action="{{ $isEdit ? route('admin.santri.update', $santri) : route('admin.santri.store') }}" method="POST" class="data-form" enctype="multipart/form-data">
|
||||
@csrf
|
||||
@if ($isEdit)
|
||||
@method('PUT')
|
||||
|
|
@ -14,6 +14,50 @@
|
|||
<small class="form-text text-muted">{{ $isEdit ? 'ID Santri tidak dapat diubah.' : 'ID akan otomatis di-generate (Contoh: ' . ($nextIdSantri ?? 'S001') . ')' }}</small>
|
||||
</div>
|
||||
|
||||
{{-- FOTO SANTRI (BARU) --}}
|
||||
<div class="form-group">
|
||||
<label for="foto">
|
||||
<i class="fas fa-image form-icon"></i>
|
||||
Foto Santri
|
||||
</label>
|
||||
|
||||
@if($isEdit && $santri->foto)
|
||||
<div style="margin-bottom: 10px;">
|
||||
<img src="{{ asset('storage/' . $santri->foto) }}"
|
||||
alt="Foto {{ $santri->nama_lengkap }}"
|
||||
style="max-width: 150px; max-height: 150px; border-radius: 8px; border: 2px solid var(--primary-light); object-fit: cover;"
|
||||
loading="lazy">
|
||||
<p style="margin-top: 5px; font-size: 0.85rem; color: var(--text-light);">
|
||||
<i class="fas fa-info-circle"></i> Foto saat ini
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<input type="file"
|
||||
id="foto"
|
||||
name="foto"
|
||||
class="form-control @error('foto') is-invalid @enderror"
|
||||
accept="image/jpeg,image/jpg,image/png"
|
||||
onchange="previewImage(event)">
|
||||
|
||||
@error('foto')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
<small class="form-text text-muted">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Format: JPG, JPEG, atau PNG. Maksimal 2 MB.
|
||||
@if($isEdit)
|
||||
Upload foto baru akan mengganti foto lama.
|
||||
@endif
|
||||
</small>
|
||||
|
||||
{{-- Preview Image --}}
|
||||
<img id="preview"
|
||||
style="display: none; margin-top: 10px; max-width: 150px; max-height: 150px; border-radius: 8px; border: 2px solid var(--primary-color); object-fit: cover;"
|
||||
loading="lazy">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nis">NIS (Nomor Induk Santri)</label>
|
||||
<input type="text" id="nis" name="nis" value="{{ old('nis', $isEdit ? $santri->nis : '') }}" class="form-control @error('nis') is-invalid @enderror" placeholder="Masukkan NIS">
|
||||
|
|
@ -94,3 +138,39 @@
|
|||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{-- JavaScript untuk Preview Image --}}
|
||||
<script>
|
||||
function previewImage(event) {
|
||||
const preview = document.getElementById('preview');
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file) {
|
||||
// Validasi ukuran file (2 MB = 2097152 bytes)
|
||||
if (file.size > 2097152) {
|
||||
alert('Ukuran file terlalu besar! Maksimal 2 MB.');
|
||||
event.target.value = '';
|
||||
preview.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
// Validasi tipe file
|
||||
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
|
||||
if (!allowedTypes.includes(file.type)) {
|
||||
alert('Format file tidak valid! Hanya JPG, JPEG, dan PNG yang diperbolehkan.');
|
||||
event.target.value = '';
|
||||
preview.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
preview.src = e.target.result;
|
||||
preview.style.display = 'block';
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
preview.style.display = 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -55,6 +55,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Foto</th>
|
||||
<th>ID Santri</th>
|
||||
<th>NIS</th>
|
||||
<th>Nama Lengkap</th>
|
||||
|
|
@ -67,7 +68,20 @@
|
|||
<tbody>
|
||||
@forelse ($santris as $index => $santri)
|
||||
<tr>
|
||||
<td>{{ $index + 1 }}</td>
|
||||
<td>{{ $santris->firstItem() + $index }}</td>
|
||||
<td>
|
||||
{{-- Foto Santri --}}
|
||||
@if($santri->foto)
|
||||
<img src="{{ asset('storage/' . $santri->foto) }}"
|
||||
alt="Foto {{ $santri->nama_lengkap }}"
|
||||
style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover; border: 2px solid var(--primary-color);"
|
||||
loading="lazy">
|
||||
@else
|
||||
<div class="santri-avatar-initial" style="width: 40px; height: 40px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 0.9rem;">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
@endif
|
||||
</td>
|
||||
<td><strong>{{ $santri->id_santri }}</strong></td>
|
||||
<td>{{ $santri->nis ?? '-' }}</td>
|
||||
<td>{{ $santri->nama_lengkap }}</td>
|
||||
|
|
@ -104,7 +118,7 @@
|
|||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="8" class="text-center" style="padding: 40px;">
|
||||
<td colspan="9" class="text-center" style="padding: 40px;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; color: #ccc; margin-bottom: 15px; display: block;"></i>
|
||||
@if(request('search') || request('status') || request('kelas'))
|
||||
<strong>Data tidak ditemukan.</strong><br>
|
||||
|
|
@ -123,15 +137,15 @@
|
|||
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #E8F7F2;">
|
||||
<p style="color: #7F8C8D; font-size: 0.9rem;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Menampilkan <strong>{{ $santris->count() }}</strong> data santri
|
||||
Menampilkan <strong>{{ $santris->count() }}</strong> dari <strong>{{ $santris->total() }}</strong> data santri
|
||||
@if(request('search') || request('status') || request('kelas'))
|
||||
dari hasil pencarian/filter
|
||||
(hasil pencarian/filter)
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Pagination (jika menggunakan paginate) -->
|
||||
<!-- Pagination -->
|
||||
@if(method_exists($santris, 'links'))
|
||||
<div style="margin-top: 20px;">
|
||||
{{ $santris->links() }}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,28 @@
|
|||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<h3>{{ $santri->nama_lengkap }}</h3>
|
||||
<p style="color: #7F8C8D; margin: 5px 0 0 0;">
|
||||
<i class="fas fa-id-badge"></i> {{ $santri->id_santri }}
|
||||
@if($santri->nis)
|
||||
| <i class="fas fa-barcode"></i> NIS: {{ $santri->nis }}
|
||||
@endif
|
||||
</p>
|
||||
<div style="display: flex; align-items: center; gap: 20px;">
|
||||
{{-- Foto Santri --}}
|
||||
@if($santri->foto)
|
||||
<img src="{{ asset('storage/' . $santri->foto) }}"
|
||||
alt="Foto {{ $santri->nama_lengkap }}"
|
||||
style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid var(--primary-color); flex-shrink: 0;"
|
||||
loading="lazy">
|
||||
@else
|
||||
<div style="width: 80px; height: 80px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; font-weight: bold; flex-shrink: 0;">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<h3>{{ $santri->nama_lengkap }}</h3>
|
||||
<p style="color: #7F8C8D; margin: 5px 0 0 0;">
|
||||
<i class="fas fa-id-badge"></i> {{ $santri->id_santri }}
|
||||
@if($santri->nis)
|
||||
| <i class="fas fa-barcode"></i> NIS: {{ $santri->nis }}
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="{{ route('admin.santri.edit', $santri) }}" class="btn btn-warning">
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 50px;
|
||||
margin-top: 30px;
|
||||
margin: 10px;
|
||||
transition: all 0.3s ease;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
|
@ -131,23 +131,20 @@
|
|||
Maaf, terjadi kesalahan pada server. Tim kami sudah diberitahu dan sedang menangani masalah ini.
|
||||
</p>
|
||||
|
||||
<?php if(isset($error) && config('app.debug')): ?>
|
||||
@if(isset($error) && config('app.debug'))
|
||||
<div class="error-message">
|
||||
<strong><i class="fas fa-bug"></i> Detail Error (Debug Mode):</strong>
|
||||
<p><?php echo e($error); ?></p>
|
||||
<?php if(isset($message)): ?>
|
||||
<p style="margin-top: 10px;"><strong>Message:</strong> <?php echo e($message); ?></p>
|
||||
<?php endif; ?>
|
||||
<p>{{ $error }}</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@endif
|
||||
|
||||
<a href="<?php echo e(url()->previous()); ?>" class="btn">
|
||||
<a href="javascript:history.back()" class="btn">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
|
||||
<a href="<?php echo e(route('santri.dashboard')); ?>" class="btn" style="margin-left: 10px;">
|
||||
<a href="{{ route('santri.dashboard') }}" class="btn">
|
||||
<i class="fas fa-home"></i> Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</body>
|
||||
</html><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/errors/500.blade.php ENDPATH**/ ?>
|
||||
</html>
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
</a>
|
||||
</li>
|
||||
|
||||
{{-- Riwayat Absensi --}}
|
||||
{{-- ✅ Kegiatan & Absensi --}}
|
||||
<li>
|
||||
<a href="#" class="{{ Request::routeIs('santri.absensi.*') ? 'active' : '' }}">
|
||||
<a href="{{ route('santri.kegiatan.index') }}" class="{{ Request::routeIs('santri.kegiatan.*') ? 'active' : '' }}">
|
||||
<i class="fas fa-calendar-check"></i>
|
||||
<span>Riwayat Absensi</span>
|
||||
<span>Kegiatan & Absensi</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@
|
|||
<h2><i class="fas fa-tachometer-alt"></i> Dashboard Progres</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
Selamat datang, <strong>{{ $data['nama_santri'] }}</strong> - Kelas {{ $data['kelas'] }}
|
||||
@if($semesterAktif)
|
||||
<span class="badge badge-success" style="margin-left: 10px;">
|
||||
<i class="fas fa-calendar-alt"></i> {{ $semesterAktif->nama_semester }}
|
||||
</span>
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -33,65 +38,57 @@
|
|||
{{-- Cards Statistik --}}
|
||||
<div class="row-cards">
|
||||
{{-- Card Progres Al-Qur'an --}}
|
||||
<div class="card card-info">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-book-quran"></i> Progres Al-Qur'an</h3>
|
||||
<div class="card-value">{{ $data['progres_quran'] }}%</div>
|
||||
<div class="card-icon"><i class="fas fa-book-quran"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: {{ $data['progres_quran'] }}%; background: var(--info-color);"></div>
|
||||
<div class="progress-fill" style="width: {{ $data['progres_quran'] }}%; background: var(--success-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Progres Hadist --}}
|
||||
<div class="card card-primary">
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-scroll"></i> Progres Hadist</h3>
|
||||
<div class="card-value">{{ $data['progres_hadist'] }}%</div>
|
||||
<div class="card-icon"><i class="fas fa-scroll"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: {{ $data['progres_hadist'] }}%; background: var(--primary-color);"></div>
|
||||
<div class="progress-fill" style="width: {{ $data['progres_hadist'] }}%; background: var(--info-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Progres Materi Tambahan --}}
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-book"></i> Materi Tambahan</h3>
|
||||
<div class="card-value">{{ $data['progres_materi_tambahan'] }}%</div>
|
||||
<div class="card-icon"><i class="fas fa-book"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: {{ $data['progres_materi_tambahan'] }}%; background: var(--warning-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Saldo Uang Saku --}}
|
||||
<div class="card card-success">
|
||||
<div class="card card-primary">
|
||||
<h3><i class="fas fa-wallet"></i> Saldo Uang Saku</h3>
|
||||
<div class="card-value">{{ 'Rp ' . number_format($data['saldo_uang_saku'], 0, ',', '.') }}</div>
|
||||
<div class="card-value-small">{{ 'Rp ' . number_format($data['saldo_uang_saku'], 0, ',', '.') }}</div>
|
||||
<div class="card-icon"><i class="fas fa-wallet"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<a href="{{ route('santri.uang-saku.index') }}" class="btn btn-sm btn-success" style="width: 100%; justify-content: center;">
|
||||
<a href="{{ route('santri.uang-saku.index') }}" class="btn btn-sm btn-primary" style="width: 100%; justify-content: center;">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Poin Pelanggaran --}}
|
||||
<div class="card card-{{ $data['poin_pelanggaran'] > 0 ? 'danger' : 'warning' }}">
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> Total Poin Pelanggaran</h3>
|
||||
<div class="card-value">{{ $data['poin_pelanggaran'] }}</div>
|
||||
<div class="card-icon"><i class="fas fa-exclamation-triangle"></i></div>
|
||||
@if($data['poin_pelanggaran'] > 0)
|
||||
<div style="margin-top: 10px;">
|
||||
<a href="{{ route('santri.pelanggaran.index') }}" class="btn btn-sm btn-danger" style="width: 100%; justify-content: center;">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
<div style="margin-top: 10px;">
|
||||
<span class="badge badge-success">
|
||||
<i class="fas fa-check-circle"></i> Tidak ada pelanggaran
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ✅ BERITA TERBARU --}}
|
||||
@if($beritaTerbaru->isNotEmpty())
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
||||
<h3 style="margin: 0; color: var(--primary-color);">
|
||||
<i class="fas fa-newspaper"></i> Berita Terbaru (7 Hari Terakhir)
|
||||
|
|
@ -125,63 +122,164 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Quick Links --}}
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h3 style="margin: 0 0 20px 0; color: var(--primary-color);">
|
||||
<i class="fas fa-bolt"></i> Akses Cepat
|
||||
</h3>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
{{-- Profil Saya --}}
|
||||
<a href="{{ route('santri.profil.index') }}" class="btn btn-primary hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-user" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Profil Saya</span>
|
||||
</a>
|
||||
|
||||
{{-- Berita --}}
|
||||
<a href="{{ route('santri.berita.index') }}" class="btn btn-info hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-newspaper" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Berita</span>
|
||||
</a>
|
||||
|
||||
{{-- Uang Saku --}}
|
||||
<a href="{{ route('santri.uang-saku.index') }}" class="btn btn-success hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-wallet" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Uang Saku</span>
|
||||
</a>
|
||||
|
||||
{{-- Pelanggaran --}}
|
||||
<a href="{{ route('santri.pelanggaran.index') }}" class="btn btn-danger hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-exclamation-circle" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Pelanggaran</span>
|
||||
</a>
|
||||
|
||||
{{-- ✅ Kesehatan (dengan badge dinamis) --}}
|
||||
<a href="{{ route('santri.kesehatan.index') }}" class="btn btn-{{ isset($statusKesehatan) && $statusKesehatan ? 'danger' : 'info' }} hover-lift" style="padding: 15px; text-align: center; position: relative;">
|
||||
<i class="fas fa-heartbeat" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Kesehatan</span>
|
||||
@if(isset($statusKesehatan) && $statusKesehatan)
|
||||
<span class="badge badge-light" style="display: block; margin-top: 5px; font-size: 0.75rem; background: rgba(255,255,255,0.9); color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-circle"></i> Sedang Dirawat
|
||||
</span>
|
||||
@endif
|
||||
</a>
|
||||
|
||||
{{-- ✅ Kepulangan (dengan badge dinamis) --}}
|
||||
<a href="{{ route('santri.kepulangan.index') }}" class="btn btn-{{ isset($kepulanganAktif) && $kepulanganAktif ? 'info' : 'primary' }} hover-lift" style="padding: 15px; text-align: center; position: relative;">
|
||||
<i class="fas fa-home" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Kepulangan</span>
|
||||
@if(isset($kepulanganAktif) && $kepulanganAktif)
|
||||
<span class="badge badge-light" style="display: block; margin-top: 5px; font-size: 0.75rem; background: rgba(255,255,255,0.9); color: var(--info-color);">
|
||||
<i class="fas fa-home"></i> Sedang Pulang
|
||||
</span>
|
||||
{{-- Card Poin Pelanggaran --}}
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px;">
|
||||
<div style="flex: 1;">
|
||||
<h3 style="margin: 0 0 5px 0; color: var(--{{ $data['poin_pelanggaran'] > 0 ? 'danger' : 'success' }}-color);">
|
||||
<i class="fas fa-exclamation-triangle"></i> Total Poin Pelanggaran: <strong>{{ $data['poin_pelanggaran'] }}</strong>
|
||||
</h3>
|
||||
@if($data['poin_pelanggaran'] > 0)
|
||||
<p style="margin: 0; color: var(--text-light); font-size: 0.9rem;">
|
||||
Anda memiliki {{ $data['poin_pelanggaran'] }} poin pelanggaran. Jaga kedisiplinan!
|
||||
</p>
|
||||
@else
|
||||
<p style="margin: 0; color: var(--text-light); font-size: 0.9rem;">
|
||||
<i class="fas fa-check-circle" style="color: var(--success-color);"></i> Alhamdulillah, tidak ada catatan pelanggaran.
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
<a href="{{ route('santri.pelanggaran.index') }}" class="btn btn-{{ $data['poin_pelanggaran'] > 0 ? 'danger' : 'success' }}">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Tips Hari Ini --}}
|
||||
<div class="content-box" style="margin-top: 20px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
{{-- ✅ SECTION GRAFIK (2 Grafik Berdampingan: Pie & Line) --}}
|
||||
@if($capaianPerMateri->count() > 0 || array_sum($distribusiStatus) > 0)
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-line"></i> Visualisasi Capaian Pembelajaran
|
||||
</h3>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 25px; margin-bottom: 30px;">
|
||||
|
||||
{{-- GRAFIK 1: Distribusi Status (PIE CHART) --}}
|
||||
@if(array_sum($distribusiStatus) > 0)
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-md); border: 2px solid var(--primary-light);">
|
||||
<h4 style="margin: 0 0 20px 0; font-size: 1.1rem; color: var(--text-color); text-align: center; font-weight: 700;">
|
||||
<i class="fas fa-chart-pie"></i> Distribusi Status Pembelajaran
|
||||
</h4>
|
||||
|
||||
{{-- Layout: Grafik di Kiri, Legend di Kanan --}}
|
||||
<div style="display: flex; align-items: center; gap: 25px; flex-wrap: wrap;">
|
||||
{{-- Grafik Pie --}}
|
||||
<div style="flex: 1; min-width: 250px; max-width: 350px;">
|
||||
<canvas id="chartPieStatus" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
|
||||
{{-- Legend/Keterangan di Samping --}}
|
||||
<div style="flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 12px;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #6FBA9D 0%, #5EA98C 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Selesai (100%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);">{{ $distribusiStatus['selesai'] }} materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #81C6E8 0%, #6AB0D4 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Hampir Selesai (75-99%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);">{{ $distribusiStatus['hampir_selesai'] }} materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #FFD56B 0%, #E6B85C 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Sedang Berjalan (25-74%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);">{{ $distribusiStatus['sedang_berjalan'] }} materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #FF8B94 0%, #E77580 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Baru Dimulai (0-24%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);">{{ $distribusiStatus['baru_dimulai'] }} materi</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 4 Kotak Statistik Berjejer Horizontal (Di Bawah) --}}
|
||||
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #f0f0f0; display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap;">
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--success-color); line-height: 1;">{{ $distribusiStatus['selesai'] }}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Selesai</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--info-color); line-height: 1;">{{ $distribusiStatus['hampir_selesai'] }}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Hampir Selesai</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #FFF8E1 0%, #FFF3CD 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--warning-color); line-height: 1;">{{ $distribusiStatus['sedang_berjalan'] }}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Sedang Berjalan</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #FFE8EA 0%, #FFD5D8 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--danger-color); line-height: 1;">{{ $distribusiStatus['baru_dimulai'] }}</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Baru Dimulai</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- GRAFIK 2: Perbandingan Kategori (LINE CHART) --}}
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-md); border: 2px solid var(--primary-light);">
|
||||
<h4 style="margin: 0 0 20px 0; font-size: 1.1rem; color: var(--text-color); text-align: center; font-weight: 700;">
|
||||
<i class="fas fa-chart-line"></i> Perbandingan Progress Kategori
|
||||
</h4>
|
||||
<div style="max-width: 450px; margin: 0 auto;">
|
||||
<canvas id="chartLineKategori" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
<div style="margin-top: 20px; display: flex; justify-content: center; gap: 20px; flex-wrap: wrap;">
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--success-color), #5EA98C); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(111, 186, 157, 0.3);">
|
||||
{{ $data['progres_quran'] }}%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Al-Qur'an</div>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--info-color), #6AB0D4); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(129, 198, 232, 0.3);">
|
||||
{{ $data['progres_hadist'] }}%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Hadist</div>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--warning-color), #E6B85C); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(255, 213, 107, 0.3);">
|
||||
{{ $data['progres_materi_tambahan'] }}%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Materi Tambahan</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- ✅ GRAFIK BATANG: Progress per Materi (SEBELUM TIPS) --}}
|
||||
@if($capaianPerMateri->count() > 0)
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-bar"></i> Progress per Materi (Top 10)
|
||||
</h3>
|
||||
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-sm); border: 2px solid var(--primary-light);">
|
||||
<canvas id="chartBarMateri" style="max-height: 450px;"></canvas>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px; text-align: center;">
|
||||
<a href="{{ route('santri.capaian.index') }}" class="btn btn-primary">
|
||||
<i class="fas fa-list"></i> Lihat Semua Capaian Detail
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- ✅ TIPS HARI INI (PALING BAWAH SENDIRI) --}}
|
||||
<div class="content-box" style="margin-top: 25px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
<h4 style="margin: 0 0 15px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-lightbulb"></i> Tips Hari Ini
|
||||
</h4>
|
||||
|
|
@ -191,4 +289,265 @@
|
|||
untuk mengetahui peraturan yang berlaku.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- Chart.js Script --}}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 1: Distribusi Status (PIE CHART)
|
||||
// ============================================
|
||||
@if(array_sum($distribusiStatus) > 0)
|
||||
const ctxPieStatus = document.getElementById('chartPieStatus');
|
||||
if (ctxPieStatus) {
|
||||
new Chart(ctxPieStatus.getContext('2d'), {
|
||||
type: 'pie',
|
||||
data: {
|
||||
// labels: ['Selesai (100%)', 'Hampir Selesai (75-99%)', 'Sedang Berjalan (25-74%)', 'Baru Dimulai (0-24%)'],
|
||||
datasets: [{
|
||||
data: [
|
||||
{{ $distribusiStatus['selesai'] }},
|
||||
{{ $distribusiStatus['hampir_selesai'] }},
|
||||
{{ $distribusiStatus['sedang_berjalan'] }},
|
||||
{{ $distribusiStatus['baru_dimulai'] }}
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.9)',
|
||||
'rgba(129, 198, 232, 0.9)',
|
||||
'rgba(255, 213, 107, 0.9)',
|
||||
'rgba(255, 139, 148, 0.9)',
|
||||
],
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 15,
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
const label = context.label || '';
|
||||
const value = context.parsed || 0;
|
||||
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
|
||||
return label + ': ' + value + ' materi (' + percentage + '%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@endif
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 2: Perbandingan Kategori (LINE CHART)
|
||||
// ============================================
|
||||
const ctxLineKategori = document.getElementById('chartLineKategori');
|
||||
if (ctxLineKategori) {
|
||||
new Chart(ctxLineKategori.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Al-Qur\'an', 'Hadist', 'Materi Tambahan'],
|
||||
datasets: [{
|
||||
label: 'Progress (%)',
|
||||
data: [
|
||||
{{ $data['progres_quran'] }},
|
||||
{{ $data['progres_hadist'] }},
|
||||
{{ $data['progres_materi_tambahan'] }}
|
||||
],
|
||||
backgroundColor: 'rgba(111, 186, 157, 0.2)',
|
||||
borderColor: 'rgba(111, 186, 157, 1)',
|
||||
borderWidth: 4,
|
||||
pointBackgroundColor: [
|
||||
'rgba(111, 186, 157, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(255, 213, 107, 1)'
|
||||
],
|
||||
pointBorderColor: '#fff',
|
||||
pointBorderWidth: 3,
|
||||
pointRadius: 8,
|
||||
pointHoverRadius: 10,
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
ticks: {
|
||||
stepSize: 20,
|
||||
callback: function(value) {
|
||||
return value + '%';
|
||||
},
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: 'rgba(0, 0, 0, 0.05)'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Progress: ' + context.parsed.y.toFixed(1) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 3: Progress per Materi (BAR CHART - Vertikal)
|
||||
// ============================================
|
||||
@if($capaianPerMateri->count() > 0)
|
||||
const ctxBarMateri = document.getElementById('chartBarMateri');
|
||||
if (ctxBarMateri) {
|
||||
new Chart(ctxBarMateri.getContext('2d'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
@foreach($capaianPerMateri as $item)
|
||||
'{{ Str::limit($item->materi->nama_kitab, 30) }}',
|
||||
@endforeach
|
||||
],
|
||||
datasets: [{
|
||||
label: 'Progress (%)',
|
||||
data: [
|
||||
@foreach($capaianPerMateri as $item)
|
||||
{{ $item->persentase }},
|
||||
@endforeach
|
||||
],
|
||||
backgroundColor: [
|
||||
@foreach($capaianPerMateri as $item)
|
||||
@if($item->materi->kategori == 'Al-Qur\'an')
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
@elseif($item->materi->kategori == 'Hadist')
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
@else
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
@endif
|
||||
@endforeach
|
||||
],
|
||||
borderColor: [
|
||||
@foreach($capaianPerMateri as $item)
|
||||
@if($item->materi->kategori == 'Al-Qur\'an')
|
||||
'rgba(111, 186, 157, 1)',
|
||||
@elseif($item->materi->kategori == 'Hadist')
|
||||
'rgba(129, 198, 232, 1)',
|
||||
@else
|
||||
'rgba(255, 213, 107, 1)',
|
||||
@endif
|
||||
@endforeach
|
||||
],
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
borderSkipped: false
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Progress: ' + context.parsed.y.toFixed(1) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
callback: function(value) {
|
||||
return value + '%';
|
||||
},
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: 'rgba(0, 0, 0, 0.05)'
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Persentase (%)',
|
||||
font: {
|
||||
size: 14,
|
||||
weight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 11
|
||||
},
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Materi',
|
||||
font: {
|
||||
size: 14,
|
||||
weight: 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@endif
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Riwayat Kegiatan & Absensi')
|
||||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-calendar-check"></i> Riwayat Kegiatan & Absensi</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
{{ $santri->nama_lengkap }} - Kelas {{ $santri->kelas }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- ✅ JADWAL KEGIATAN HARI INI --}}
|
||||
<div class="content-box" style="margin-bottom: 25px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
||||
<h3 style="margin: 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-clock"></i> Jadwal Kegiatan Hari Ini ({{ ucfirst($hariIni) }})
|
||||
</h3>
|
||||
<span class="badge badge-primary badge-lg">
|
||||
<i class="fas fa-calendar-day"></i> {{ \Carbon\Carbon::now()->locale('id')->isoFormat('D MMMM YYYY') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@if($jadwalHariIni->count() > 0)
|
||||
<div style="display: flex; flex-direction: column; gap: 12px;">
|
||||
@foreach($jadwalHariIni as $jadwal)
|
||||
<div style="background: white; padding: 18px; border-radius: var(--border-radius-sm); border-left: 4px solid {{ isset($absensiHariIni[$jadwal->kegiatan_id]) ? 'var(--success-color)' : 'var(--warning-color)' }}; display: flex; justify-content: space-between; align-items: center; box-shadow: var(--shadow-sm);">
|
||||
<div style="flex: 1;">
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
|
||||
<span class="badge badge-info">{{ $jadwal->kategori->nama_kategori }}</span>
|
||||
<h4 style="margin: 0; font-size: 1.1rem; color: var(--text-color);">{{ $jadwal->nama_kegiatan }}</h4>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 15px; font-size: 0.9rem; color: var(--text-light);">
|
||||
<span><i class="fas fa-clock"></i> {{ date('H:i', strtotime($jadwal->waktu_mulai)) }} - {{ date('H:i', strtotime($jadwal->waktu_selesai)) }}</span>
|
||||
@if($jadwal->materi)
|
||||
<span><i class="fas fa-book"></i> {{ $jadwal->materi }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@if(isset($absensiHariIni[$jadwal->kegiatan_id]))
|
||||
<span class="badge badge-success badge-lg">
|
||||
<i class="fas fa-check-circle"></i> {{ $absensiHariIni[$jadwal->kegiatan_id] }}
|
||||
</span>
|
||||
@else
|
||||
<span class="badge badge-warning badge-lg">
|
||||
<i class="fas fa-hourglass-half"></i> Belum Absen
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state" style="padding: 40px; text-align: center;">
|
||||
<i class="fas fa-calendar-times" style="font-size: 3rem; color: #ccc;"></i>
|
||||
<p style="margin-top: 15px; color: var(--text-light);">Tidak ada jadwal kegiatan untuk hari ini.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- ✅ STATISTIK KEHADIRAN 30 HARI TERAKHIR --}}
|
||||
<div class="row-cards" style="margin-bottom: 25px;">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-check-circle"></i> Total Kehadiran</h3>
|
||||
<div class="card-value">{{ $stats30Hari['Hadir'] ?? 0 }}</div>
|
||||
<div class="card-icon"><i class="fas fa-check-circle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">30 hari terakhir</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-percentage"></i> Persentase Kehadiran</h3>
|
||||
<div class="card-value">{{ $persentaseKehadiran }}%</div>
|
||||
<div class="card-icon"><i class="fas fa-chart-line"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: {{ $persentaseKehadiran }}%; background: var(--info-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> Izin / Sakit / Alpa</h3>
|
||||
<div class="card-value">{{ ($stats30Hari['Izin'] ?? 0) + ($stats30Hari['Sakit'] ?? 0) + ($stats30Hari['Alpa'] ?? 0) }}</div>
|
||||
<div class="card-icon"><i class="fas fa-exclamation-triangle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Izin: {{ $stats30Hari['Izin'] ?? 0 }} | Sakit: {{ $stats30Hari['Sakit'] ?? 0 }} | Alpa: {{ $stats30Hari['Alpa'] ?? 0 }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<h3><i class="fas fa-list-check"></i> Total Kegiatan</h3>
|
||||
<div class="card-value">{{ $totalKegiatan30Hari }}</div>
|
||||
<div class="card-icon"><i class="fas fa-list-check"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">30 hari terakhir</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ✅ GRAFIK KEHADIRAN MINGGUAN & PER KATEGORI (SIDE BY SIDE) --}}
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); gap: 25px; margin-bottom: 25px;">
|
||||
|
||||
{{-- GRAFIK 1: Kehadiran per Minggu (LINE CHART) --}}
|
||||
<div class="content-box">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-line"></i> Tren Kehadiran (4 Minggu Terakhir)
|
||||
</h3>
|
||||
<canvas id="chartTrenKehadiran" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
|
||||
{{-- GRAFIK 2: Kehadiran per Kategori (BAR CHART) --}}
|
||||
<div class="content-box">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-bar"></i> Kehadiran per Kategori Kegiatan
|
||||
</h3>
|
||||
<canvas id="chartKategori" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ✅ FILTER & RIWAYAT ABSENSI --}}
|
||||
<div class="content-box">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px;">
|
||||
<h3 style="margin: 0; color: var(--text-color);">
|
||||
<i class="fas fa-history"></i> Riwayat Absensi Lengkap
|
||||
</h3>
|
||||
|
||||
{{-- Form Filter --}}
|
||||
<form method="GET" action="{{ route('santri.kegiatan.index') }}" style="display: flex; gap: 10px; flex-wrap: wrap;">
|
||||
<input type="month" name="bulan" class="form-control" value="{{ request('bulan') }}"
|
||||
style="max-width: 200px;" placeholder="Pilih Bulan">
|
||||
<select name="status" class="form-control" style="max-width: 150px;">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="Hadir" {{ request('status') == 'Hadir' ? 'selected' : '' }}>Hadir</option>
|
||||
<option value="Izin" {{ request('status') == 'Izin' ? 'selected' : '' }}>Izin</option>
|
||||
<option value="Sakit" {{ request('status') == 'Sakit' ? 'selected' : '' }}>Sakit</option>
|
||||
<option value="Alpa" {{ request('status') == 'Alpa' ? 'selected' : '' }}>Alpa</option>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
<a href="{{ route('santri.kegiatan.index') }}" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@if($riwayats->count() > 0)
|
||||
<div class="table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Kegiatan</th>
|
||||
<th>Kategori</th>
|
||||
<th>Waktu Absen</th>
|
||||
<th>Status</th>
|
||||
<th>Metode</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($riwayats as $index => $absensi)
|
||||
<tr>
|
||||
<td>{{ $riwayats->firstItem() + $index }}</td>
|
||||
<td>{{ $absensi->tanggal_formatted }}</td>
|
||||
<td><strong>{{ $absensi->kegiatan->nama_kegiatan }}</strong></td>
|
||||
<td><span class="badge badge-info">{{ $absensi->kegiatan->kategori->nama_kategori }}</span></td>
|
||||
<td>{{ $absensi->waktu_absen_formatted }}</td>
|
||||
<td>
|
||||
<span class="badge {{ $absensi->status_badge_class }}">
|
||||
<i class="fas fa-{{ $absensi->status == 'Hadir' ? 'check' : ($absensi->status == 'Izin' ? 'info-circle' : ($absensi->status == 'Sakit' ? 'heartbeat' : 'times')) }}-circle"></i>
|
||||
{{ $absensi->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td><span class="badge badge-secondary">{{ $absensi->metode_absen }}</span></td>
|
||||
<td class="text-center">
|
||||
<a href="{{ route('santri.kegiatan.show', $absensi->kegiatan_id) }}" class="btn btn-sm btn-primary" title="Lihat Detail Kegiatan">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Pagination --}}
|
||||
<div style="margin-top: 20px;">
|
||||
{{ $riwayats->links() }}
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox"></i>
|
||||
<h3>Belum Ada Riwayat Absensi</h3>
|
||||
<p>Riwayat absensi Anda akan muncul di sini setelah mengikuti kegiatan.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Chart.js Script --}}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 1: Tren Kehadiran per Minggu (LINE CHART)
|
||||
// ============================================
|
||||
const ctxTren = document.getElementById('chartTrenKehadiran');
|
||||
if (ctxTren) {
|
||||
new Chart(ctxTren.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [
|
||||
@foreach($dataGrafikMingguan as $data)
|
||||
'{{ $data["minggu"] }}',
|
||||
@endforeach
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Hadir',
|
||||
data: [
|
||||
@foreach($dataGrafikMingguan as $data)
|
||||
{{ $data['hadir'] }},
|
||||
@endforeach
|
||||
],
|
||||
borderColor: 'rgba(111, 186, 157, 1)',
|
||||
backgroundColor: 'rgba(111, 186, 157, 0.2)',
|
||||
borderWidth: 3,
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: 'rgba(111, 186, 157, 1)',
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
},
|
||||
{
|
||||
label: 'Total Kegiatan',
|
||||
data: [
|
||||
@foreach($dataGrafikMingguan as $data)
|
||||
{{ $data['total'] }},
|
||||
@endforeach
|
||||
],
|
||||
borderColor: 'rgba(129, 198, 232, 1)',
|
||||
backgroundColor: 'rgba(129, 198, 232, 0.1)',
|
||||
borderWidth: 2,
|
||||
pointRadius: 4,
|
||||
pointBackgroundColor: 'rgba(129, 198, 232, 1)',
|
||||
tension: 0.4,
|
||||
fill: true,
|
||||
borderDash: [5, 5]
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
labels: {
|
||||
font: { size: 12, weight: '600' },
|
||||
padding: 15
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return context.dataset.label + ': ' + context.parsed.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1,
|
||||
font: { size: 12, weight: '600' }
|
||||
},
|
||||
grid: { color: 'rgba(0, 0, 0, 0.05)' }
|
||||
},
|
||||
x: {
|
||||
ticks: { font: { size: 12, weight: '600' } },
|
||||
grid: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 2: Kehadiran per Kategori (BAR CHART)
|
||||
// ============================================
|
||||
const ctxKategori = document.getElementById('chartKategori');
|
||||
if (ctxKategori) {
|
||||
new Chart(ctxKategori.getContext('2d'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
@foreach($statsByKategori as $stat)
|
||||
'{{ $stat->nama_kategori }}',
|
||||
@endforeach
|
||||
],
|
||||
datasets: [{
|
||||
label: 'Kehadiran',
|
||||
data: [
|
||||
@foreach($statsByKategori as $stat)
|
||||
{{ $stat->hadir }},
|
||||
@endforeach
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
'rgba(255, 139, 148, 0.8)',
|
||||
'rgba(179, 157, 219, 0.8)',
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(111, 186, 157, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(255, 213, 107, 1)',
|
||||
'rgba(255, 139, 148, 1)',
|
||||
'rgba(179, 157, 219, 1)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
borderSkipped: false
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Hadir: ' + context.parsed.y + ' kali';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1,
|
||||
font: { size: 12, weight: '600' }
|
||||
},
|
||||
grid: { color: 'rgba(0, 0, 0, 0.05)' }
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: { size: 11 },
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
},
|
||||
grid: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Detail Riwayat Kegiatan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-clipboard-list"></i> Detail Riwayat Kegiatan</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
{{ $santri->nama_lengkap }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- ✅ INFO KEGIATAN --}}
|
||||
<div class="content-box" style="margin-bottom: 25px; background: linear-gradient(135deg, #FFFFFF 0%, #F8FBF9 100%); border: 2px solid var(--primary-light);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px; margin-bottom: 20px;">
|
||||
<div>
|
||||
<h3 style="margin: 0 0 8px 0; color: var(--primary-dark); font-size: 1.5rem;">
|
||||
{{ $kegiatan->nama_kegiatan }}
|
||||
</h3>
|
||||
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap;">
|
||||
<span class="badge badge-info badge-lg">
|
||||
<i class="fas fa-tag"></i> {{ $kegiatan->kategori->nama_kategori }}
|
||||
</span>
|
||||
<span class="badge badge-primary badge-lg">
|
||||
<i class="fas fa-calendar-day"></i> {{ $kegiatan->hari }}
|
||||
</span>
|
||||
<span class="badge badge-secondary badge-lg">
|
||||
<i class="fas fa-clock"></i> {{ date('H:i', strtotime($kegiatan->waktu_mulai)) }} - {{ date('H:i', strtotime($kegiatan->waktu_selesai)) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('santri.kegiatan.index') }}" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@if($kegiatan->materi)
|
||||
<div style="padding: 15px; background: var(--primary-light); border-radius: var(--border-radius-sm); margin-bottom: 15px;">
|
||||
<strong><i class="fas fa-book"></i> Materi:</strong> {{ $kegiatan->materi }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($kegiatan->keterangan)
|
||||
<div style="padding: 15px; background: #FFF8E1; border-radius: var(--border-radius-sm); border-left: 4px solid var(--warning-color);">
|
||||
<strong><i class="fas fa-info-circle"></i> Keterangan:</strong><br>
|
||||
{{ $kegiatan->keterangan }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- ✅ STATISTIK KEHADIRAN UNTUK KEGIATAN INI --}}
|
||||
<div class="row-cards" style="margin-bottom: 25px;">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-check-circle"></i> Total Hadir</h3>
|
||||
<div class="card-value">{{ $stats['Hadir'] ?? 0 }}</div>
|
||||
<div class="card-icon"><i class="fas fa-check-circle"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-info-circle"></i> Izin</h3>
|
||||
<div class="card-value">{{ $stats['Izin'] ?? 0 }}</div>
|
||||
<div class="card-icon"><i class="fas fa-info-circle"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-heartbeat"></i> Sakit</h3>
|
||||
<div class="card-value">{{ $stats['Sakit'] ?? 0 }}</div>
|
||||
<div class="card-icon"><i class="fas fa-heartbeat"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="card card-danger">
|
||||
<h3><i class="fas fa-times-circle"></i> Alpa</h3>
|
||||
<div class="card-value">{{ $stats['Alpa'] ?? 0 }}</div>
|
||||
<div class="card-icon"><i class="fas fa-times-circle"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ✅ GRAFIK PIE: Distribusi Status Kehadiran --}}
|
||||
<div class="content-box" style="margin-bottom: 25px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark); text-align: center;">
|
||||
<i class="fas fa-chart-pie"></i> Distribusi Status Kehadiran
|
||||
</h3>
|
||||
|
||||
<div style="max-width: 400px; margin: 0 auto;">
|
||||
<canvas id="chartDistribusiStatus" style="max-height: 350px;"></canvas>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 25px; text-align: center; padding-top: 20px; border-top: 1px solid #f0f0f0;">
|
||||
<div style="display: inline-block; padding: 15px 30px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border-radius: var(--border-radius); box-shadow: var(--shadow-sm);">
|
||||
<div style="font-size: 0.9rem; color: var(--text-light); margin-bottom: 5px;">Persentase Kehadiran</div>
|
||||
<div style="font-size: 2.5rem; font-weight: 700; color: var(--success-color);">{{ $persentaseHadir }}%</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-light); margin-top: 5px;">dari {{ $totalAbsensi }} total absensi</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ✅ RIWAYAT ABSENSI LENGKAP --}}
|
||||
<div class="content-box">
|
||||
<h3 style="margin-bottom: 20px; color: var(--text-color);">
|
||||
<i class="fas fa-history"></i> Riwayat Absensi Lengkap
|
||||
</h3>
|
||||
|
||||
@if($riwayats->count() > 0)
|
||||
<div class="table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Hari</th>
|
||||
<th>Waktu Absen</th>
|
||||
<th>Status</th>
|
||||
<th>Metode</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($riwayats as $index => $absensi)
|
||||
<tr>
|
||||
<td>{{ $riwayats->firstItem() + $index }}</td>
|
||||
<td>{{ $absensi->tanggal_formatted }}</td>
|
||||
<td>{{ \Carbon\Carbon::parse($absensi->tanggal)->locale('id')->dayName }}</td>
|
||||
<td>{{ $absensi->waktu_absen_formatted }}</td>
|
||||
<td>
|
||||
<span class="badge {{ $absensi->status_badge_class }}">
|
||||
<i class="fas fa-{{ $absensi->status == 'Hadir' ? 'check' : ($absensi->status == 'Izin' ? 'info-circle' : ($absensi->status == 'Sakit' ? 'heartbeat' : 'times')) }}-circle"></i>
|
||||
{{ $absensi->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td><span class="badge badge-secondary">{{ $absensi->metode_absen }}</span></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Pagination --}}
|
||||
<div style="margin-top: 20px;">
|
||||
{{ $riwayats->links() }}
|
||||
</div>
|
||||
@else
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox"></i>
|
||||
<h3>Belum Ada Riwayat</h3>
|
||||
<p>Anda belum pernah mengikuti kegiatan ini atau belum ada data absensi yang tercatat.</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Chart.js Script --}}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// ============================================
|
||||
// GRAFIK PIE: Distribusi Status Kehadiran
|
||||
// ============================================
|
||||
const ctxPie = document.getElementById('chartDistribusiStatus');
|
||||
if (ctxPie) {
|
||||
new Chart(ctxPie.getContext('2d'), {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Hadir', 'Izin', 'Sakit', 'Alpa'],
|
||||
datasets: [{
|
||||
data: [
|
||||
{{ $stats['Hadir'] ?? 0 }},
|
||||
{{ $stats['Izin'] ?? 0 }},
|
||||
{{ $stats['Sakit'] ?? 0 }},
|
||||
{{ $stats['Alpa'] ?? 0 }}
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.9)',
|
||||
'rgba(129, 198, 232, 0.9)',
|
||||
'rgba(255, 213, 107, 0.9)',
|
||||
'rgba(255, 139, 148, 0.9)',
|
||||
],
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 20,
|
||||
font: {
|
||||
size: 13,
|
||||
weight: '600'
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
const label = context.label || '';
|
||||
const value = context.parsed || 0;
|
||||
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
|
||||
return label + ': ' + value + ' kali (' + percentage + '%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
<!-- resources/views/santri/profil/index.blade.php -->
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Profil Santri')
|
||||
|
|
|
|||
|
|
@ -18,10 +18,21 @@
|
|||
{{-- Header Profil --}}
|
||||
<div class="detail-header">
|
||||
<div style="display: flex; align-items: center; gap: 20px;">
|
||||
{{-- Avatar Santri --}}
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
{{-- Foto Santri --}}
|
||||
@if($santri->foto && file_exists(public_path('storage/' . $santri->foto)))
|
||||
<img src="{{ asset('storage/' . $santri->foto) }}"
|
||||
alt="Foto {{ $santri->nama_lengkap }}"
|
||||
style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid var(--primary-color); flex-shrink: 0;"
|
||||
loading="lazy"
|
||||
onerror="this.onerror=null; this.style.display='none'; this.nextElementSibling.style.display='flex';">
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg" style="display: none;">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
@else
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg">
|
||||
{{ strtoupper(substr($santri->nama_lengkap, 0, 1)) }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<h3 style="margin: 0; font-size: 1.8rem; color: var(--text-color);">
|
||||
|
|
@ -146,7 +157,7 @@
|
|||
<div style="margin-top: 30px; padding: 20px; background: var(--primary-light); border-radius: var(--border-radius-sm); border-left: 4px solid var(--primary-color);">
|
||||
<p style="margin: 0; color: var(--text-color); line-height: 1.6;">
|
||||
<i class="fas fa-info-circle" style="color: var(--primary-color);"></i>
|
||||
<strong>Catatan:</strong> Jika ada data yang perlu diperbarui selain alamat dan nomor HP orang tua, silakan hubungi admin atau pengurus pesantren.
|
||||
<strong>Catatan:</strong> Jika ada data yang perlu diperbarui termasuk foto profil, silakan hubungi admin atau pengurus pesantren.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,19 +1,32 @@
|
|||
<?php
|
||||
// routes/api.php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\Api\ApiAuthController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
| API Routes untuk Mobile App
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider and all of them will
|
||||
| be assigned to the "api" middleware group. Make something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
// Public routes (tanpa auth)
|
||||
Route::prefix('v1')->group(function () {
|
||||
// Login
|
||||
Route::post('/login', [ApiAuthController::class, 'login']);
|
||||
});
|
||||
|
||||
// Protected routes (butuh token)
|
||||
Route::prefix('v1')->middleware('auth:sanctum')->group(function () {
|
||||
// Logout
|
||||
Route::post('/logout', [ApiAuthController::class, 'logout']);
|
||||
|
||||
// Profile
|
||||
Route::get('/profile', [ApiAuthController::class, 'profile']);
|
||||
|
||||
// TODO: Tambahkan endpoint lain di sini
|
||||
// Route::get('/uang-saku', [ApiUangSakuController::class, 'index']);
|
||||
// Route::get('/pelanggaran', [ApiPelanggaranController::class, 'index']);
|
||||
// dst...
|
||||
});
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
use App\Http\Controllers\Santri\SantriKesehatanController;
|
||||
use App\Http\Controllers\Santri\SantriCapaianController;
|
||||
use App\Http\Controllers\Santri\SantriKepulanganController;
|
||||
use App\Http\Controllers\Santri\RiwayatKegiatanSantriController; // ✅ TAMBAHKAN INI
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -67,7 +68,8 @@
|
|||
// --- RUTE ADMINISTRATOR (Prefix: admin) ---
|
||||
Route::prefix('admin')
|
||||
->middleware(['auth', 'role:admin'])
|
||||
->name('admin.')->group(function () {
|
||||
->name('admin.')
|
||||
->group(function () {
|
||||
|
||||
// Logout Admin
|
||||
Route::post('logout', [AdminAuthController::class, 'logout'])->name('logout');
|
||||
|
|
@ -110,35 +112,40 @@
|
|||
'cetakSurat'
|
||||
])->name('kesehatan-santri.cetak-surat');
|
||||
|
||||
// 5. KEPULANGAN SANTRI
|
||||
Route::resource('kepulangan', KepulanganController::class);
|
||||
// 5. KEPULANGAN SANTRI (UPDATED - LENGKAP) ✅
|
||||
Route::prefix('kepulangan')->name('kepulangan.')->group(function () {
|
||||
|
||||
// Route tambahan untuk approve/reject
|
||||
Route::post('kepulangan/{kepulangan}/approve', [
|
||||
KepulanganController::class,
|
||||
'approve'
|
||||
])->name('kepulangan.approve');
|
||||
// Main CRUD
|
||||
Route::get('/', [KepulanganController::class, 'index'])->name('index');
|
||||
Route::get('/create', [KepulanganController::class, 'create'])->name('create');
|
||||
Route::post('/', [KepulanganController::class, 'store'])->name('store');
|
||||
Route::get('/{id_kepulangan}', [KepulanganController::class, 'show'])->name('show');
|
||||
Route::get('/{id_kepulangan}/edit', [KepulanganController::class, 'edit'])->name('edit');
|
||||
Route::put('/{id_kepulangan}', [KepulanganController::class, 'update'])->name('update');
|
||||
Route::delete('/{id_kepulangan}', [KepulanganController::class, 'destroy'])->name('destroy');
|
||||
|
||||
Route::post('kepulangan/{kepulangan}/reject', [
|
||||
KepulanganController::class,
|
||||
'reject'
|
||||
])->name('kepulangan.reject');
|
||||
// Actions (Approval/Reject/Complete)
|
||||
Route::post('/{id_kepulangan}/approve', [KepulanganController::class, 'approve'])->name('approve');
|
||||
Route::post('/{id_kepulangan}/reject', [KepulanganController::class, 'reject'])->name('reject');
|
||||
Route::post('/{id_kepulangan}/complete', [KepulanganController::class, 'complete'])->name('complete');
|
||||
|
||||
Route::post('kepulangan/{kepulangan}/complete', [
|
||||
KepulanganController::class,
|
||||
'complete'
|
||||
])->name('kepulangan.complete');
|
||||
// Print Surat Izin
|
||||
Route::get('/{id_kepulangan}/print', [KepulanganController::class, 'print'])->name('print');
|
||||
|
||||
Route::get('kepulangan/{kepulangan}/print', [
|
||||
KepulanganController::class,
|
||||
'print'
|
||||
])->name('kepulangan.print');
|
||||
// Settings & Manajemen Kuota
|
||||
Route::get('/settings/manage', [KepulanganController::class, 'settings'])->name('settings');
|
||||
Route::put('/settings/update', [KepulanganController::class, 'updateSettings'])->name('settings.update');
|
||||
|
||||
// API route untuk get santri data
|
||||
Route::get('api/kepulangan/santri/{id_santri}', [
|
||||
KepulanganController::class,
|
||||
'getSantriData'
|
||||
])->name('api.kepulangan.santri');
|
||||
// Reset Kuota
|
||||
Route::post('/reset/santri/{id_santri}', [KepulanganController::class, 'resetKuotaSantri'])->name('reset.santri');
|
||||
Route::post('/reset/semua', [KepulanganController::class, 'resetKuotaSemuaSantri'])->name('reset.semua');
|
||||
|
||||
// List Santri Over Limit
|
||||
Route::get('/over-limit/list', [KepulanganController::class, 'santriOverLimit'])->name('over-limit');
|
||||
|
||||
// API untuk AJAX (Get Santri Data)
|
||||
Route::get('/api/santri/{id_santri}', [KepulanganController::class, 'getSantriData'])->name('api.santri');
|
||||
});
|
||||
|
||||
// 6. BERITA
|
||||
Route::prefix('berita')->name('berita.')->group(function () {
|
||||
|
|
@ -332,4 +339,10 @@
|
|||
Route::get('/', [SantriKepulanganController::class, 'index'])->name('index');
|
||||
Route::get('/{kepulangan:id_kepulangan}', [SantriKepulanganController::class, 'show'])->name('show');
|
||||
});
|
||||
|
||||
// 8. RIWAYAT KEGIATAN & ABSENSI (BARU ✅)
|
||||
Route::prefix('kegiatan')->name('kegiatan.')->group(function () {
|
||||
Route::get('/', [\App\Http\Controllers\Santri\RiwayatKegiatanSantriController::class, 'index'])->name('index');
|
||||
Route::get('/{kegiatan_id}', [\App\Http\Controllers\Santri\RiwayatKegiatanSantriController::class, 'show'])->name('show');
|
||||
});
|
||||
});
|
||||
|
|
@ -1 +0,0 @@
|
|||
a:4:{s:6:"_token";s:40:"8ML9ZdqWCLmjAek9Pi9CSKX0CGiYJqxIKIH97x95";s:3:"url";a:1:{s:8:"intended";s:37:"http://127.0.0.1:8000/admin/dashboard";}s:9:"_previous";a:1:{s:3:"url";s:37:"http://127.0.0.1:8000/admin/dashboard";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
||||
|
|
@ -1 +0,0 @@
|
|||
a:4:{s:6:"_token";s:40:"tLWa7PcNO0JI4f1QHde6luLyp4Ex4H9kRkY0yFqo";s:13:"last_activity";i:1763627918;s:9:"_previous";a:1:{s:3:"url";s:33:"http://127.0.0.1:8000/admin/login";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
a:3:{s:6:"_token";s:40:"HMiLcFVcm6pBs2CoAThDnWeSql4wY7Rg2wcESX53";s:7:"success";s:21:"Anda berhasil logout.";s:6:"_flash";a:2:{s:3:"new";a:0:{}s:3:"old";a:1:{i:0;s:7:"success";}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
a:4:{s:6:"_token";s:40:"vvFpRFUMLEugpbL26sTeoMo21ei7FQXxYJzYURcb";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}s:3:"url";a:1:{s:8:"intended";s:37:"http://127.0.0.1:8000/admin/dashboard";}s:9:"_previous";a:1:{s:3:"url";s:37:"http://127.0.0.1:8000/admin/dashboard";}}
|
||||
|
|
@ -1 +0,0 @@
|
|||
a:6:{s:6:"_token";s:40:"9vNjPLLee09wl7aDFMu598IYqYrzhRXo2tGcpKYW";s:50:"login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d";i:2;s:17:"password_hash_web";s:60:"$2y$12$2MjNMVyBNLiANDZq0.J7E.wltuOfMH21Eqqx4teTEcr1T4ZayVGGq";s:13:"last_activity";i:1763627930;s:9:"_previous";a:1:{s:3:"url";s:38:"http://127.0.0.1:8000/santri/dashboard";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
a:4:{s:6:"_token";s:40:"iGl6a2chuGMqLNfaeXnP152fY8roRVN4aQ3CaDBW";s:13:"last_activity";i:1767673469;s:9:"_previous";a:1:{s:3:"url";s:33:"http://127.0.0.1:8000/admin/login";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Not Found')); ?>
|
||||
<?php $__env->startSection('code', '404'); ?>
|
||||
<?php $__env->startSection('message', __('Not Found')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions/views/404.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Capaian'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-book-reader"></i> Detail Capaian</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<h3><i class="fas fa-info-circle"></i> Informasi Capaian</h3>
|
||||
<a href="<?php echo e(route('santri.capaian.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-book"></i> Informasi Materi</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>Nama Materi</th>
|
||||
<td><strong><?php echo e($capaian->materi->nama_kitab); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kategori</th>
|
||||
<td>
|
||||
<span class="badge
|
||||
<?php if($capaian->materi->kategori == 'Al-Qur\'an'): ?> badge-success
|
||||
<?php elseif($capaian->materi->kategori == 'Hadist'): ?> badge-info
|
||||
<?php else: ?> badge-warning
|
||||
<?php endif; ?>
|
||||
">
|
||||
<?php echo e($capaian->materi->kategori); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Total Halaman</th>
|
||||
<td><?php echo e($capaian->materi->total_halaman); ?> halaman (Hal. <?php echo e($capaian->materi->halaman_mulai); ?> - <?php echo e($capaian->materi->halaman_akhir); ?>)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-chart-line"></i> Progress Pembelajaran</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>Persentase Selesai</th>
|
||||
<td>
|
||||
<div style="display: flex; align-items: center; gap: 15px;">
|
||||
<div class="progress-bar" style="flex: 1;">
|
||||
<div class="progress-fill" style="width: <?php echo e($capaian->persentase); ?>%; background:
|
||||
<?php if($capaian->persentase >= 100): ?> var(--success-color)
|
||||
<?php elseif($capaian->persentase >= 75): ?> var(--info-color)
|
||||
<?php elseif($capaian->persentase >= 50): ?> var(--warning-color)
|
||||
<?php else: ?> var(--danger-color)
|
||||
<?php endif; ?>
|
||||
;"></div>
|
||||
</div>
|
||||
<span style="font-weight: 700; font-size: 1.2rem; color: var(--primary-color);">
|
||||
<?php echo e(number_format($capaian->persentase, 2)); ?>%
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Jumlah Halaman Selesai</th>
|
||||
<td>
|
||||
<strong style="color: var(--primary-color); font-size: 1.1rem;">
|
||||
<?php echo e(count($capaian->pages_array)); ?>
|
||||
|
||||
</strong> dari <?php echo e($capaian->materi->total_halaman); ?> halaman
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Detail Halaman Selesai</th>
|
||||
<td>
|
||||
<div style="background: var(--primary-light); padding: 12px; border-radius: var(--border-radius-sm); font-family: monospace; color: var(--text-color); line-height: 1.8;">
|
||||
<?php echo e($capaian->halaman_selesai); ?>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tanggal Input</th>
|
||||
<td><?php echo e(\Carbon\Carbon::parse($capaian->tanggal_input)->format('d F Y')); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Semester</th>
|
||||
<td>
|
||||
<span class="badge badge-primary">
|
||||
<?php echo e($capaian->semester->nama_semester); ?> - <?php echo e($capaian->semester->tahun_ajaran); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if($capaian->catatan): ?>
|
||||
<tr>
|
||||
<th>Catatan</th>
|
||||
<td>
|
||||
<div style="background: #FFF8E1; padding: 12px; border-radius: var(--border-radius-sm); border-left: 4px solid var(--warning-color);">
|
||||
<i class="fas fa-sticky-note" style="color: var(--warning-color); margin-right: 8px;"></i>
|
||||
<?php echo e($capaian->catatan); ?>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-th"></i> Visualisasi Halaman yang Diselesaikan</h4>
|
||||
<div style="background: white; padding: 20px; border-radius: var(--border-radius-sm); box-shadow: var(--shadow-sm);">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 8px;">
|
||||
<?php
|
||||
$completedPages = $capaian->pages_array;
|
||||
$totalPages = $capaian->materi->total_halaman;
|
||||
$startPage = $capaian->materi->halaman_mulai;
|
||||
?>
|
||||
|
||||
<?php for($i = $startPage; $i <= ($startPage + $totalPages - 1); $i++): ?>
|
||||
<?php
|
||||
$isCompleted = in_array($i, $completedPages);
|
||||
?>
|
||||
<div style="
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
<?php echo e($isCompleted
|
||||
? 'background: linear-gradient(135deg, var(--success-color), #5EA98C); color: white; box-shadow: 0 2px 4px rgba(111, 186, 157, 0.3);'
|
||||
: 'background: #F5F5F5; color: #999; border: 1px dashed #ddd;'); ?>
|
||||
|
||||
">
|
||||
<?php echo e($i); ?>
|
||||
|
||||
</div>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; justify-content: center; gap: 25px; margin-top: 20px; padding-top: 15px; border-top: 1px solid #E0E0E0;">
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<div style="width: 20px; height: 20px; background: linear-gradient(135deg, var(--success-color), #5EA98C); border-radius: 4px;"></div>
|
||||
<span style="font-size: 0.85rem; color: var(--text-color);">Selesai (<?php echo e(count($completedPages)); ?>)</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 8px;">
|
||||
<div style="width: 20px; height: 20px; background: #F5F5F5; border: 1px dashed #ddd; border-radius: 4px;"></div>
|
||||
<span style="font-size: 0.85rem; color: var(--text-color);">Belum (<?php echo e($totalPages - count($completedPages)); ?>)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="text-align: center; margin-top: 30px;">
|
||||
<?php if($capaian->persentase >= 100): ?>
|
||||
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 20px; border-radius: var(--border-radius); border: 2px solid var(--success-color);">
|
||||
<i class="fas fa-check-circle" style="font-size: 3rem; color: var(--success-color); margin-bottom: 10px;"></i>
|
||||
<h3 style="margin: 0; color: #155724;">Alhamdulillah, Materi Selesai! 🎉</h3>
|
||||
<p style="margin: 8px 0 0 0; color: #155724;">Terus semangat untuk materi berikutnya!</p>
|
||||
</div>
|
||||
<?php elseif($capaian->persentase >= 75): ?>
|
||||
<div style="background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%); padding: 20px; border-radius: var(--border-radius); border: 2px solid var(--info-color);">
|
||||
<i class="fas fa-fire" style="font-size: 3rem; color: var(--info-color); margin-bottom: 10px;"></i>
|
||||
<h3 style="margin: 0; color: #0c5460;">Hampir Selesai! 💪</h3>
|
||||
<p style="margin: 8px 0 0 0; color: #0c5460;">Tinggal sedikit lagi, pertahankan semangatmu!</p>
|
||||
</div>
|
||||
<?php elseif($capaian->persentase >= 50): ?>
|
||||
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%); padding: 20px; border-radius: var(--border-radius); border: 2px solid var(--warning-color);">
|
||||
<i class="fas fa-hourglass-half" style="font-size: 3rem; color: var(--warning-color); margin-bottom: 10px;"></i>
|
||||
<h3 style="margin: 0; color: #856404;">Setengah Perjalanan! ⚡</h3>
|
||||
<p style="margin: 8px 0 0 0; color: #856404;">Terus berjuang, jangan menyerah!</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%); padding: 20px; border-radius: var(--border-radius); border: 2px solid var(--danger-color);">
|
||||
<i class="fas fa-seedling" style="font-size: 3rem; color: var(--danger-color); margin-bottom: 10px;"></i>
|
||||
<h3 style="margin: 0; color: #721c24;">Baru Memulai! 🌱</h3>
|
||||
<p style="margin: 8px 0 0 0; color: #721c24;">Setiap perjalanan dimulai dari langkah pertama. Semangat!</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/capaian/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Riwayat Pelanggaran'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-exclamation-circle"></i> Riwayat Pelanggaran Saya</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-danger">
|
||||
<h3>Total Pelanggaran</h3>
|
||||
<div class="card-value"><?php echo e($totalPelanggaran); ?></div>
|
||||
<i class="fas fa-exclamation-triangle card-icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3>Total Poin</h3>
|
||||
<div class="card-value"><?php echo e($totalPoin); ?></div>
|
||||
<i class="fas fa-star card-icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="card card-info">
|
||||
<h3>Pelanggaran Bulan Ini</h3>
|
||||
<div class="card-value"><?php echo e($pelanggaranBulanIni); ?></div>
|
||||
<i class="fas fa-calendar-alt card-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px;">
|
||||
<form method="GET" action="<?php echo e(route('santri.pelanggaran.index')); ?>" style="display: flex; gap: 10px; flex-wrap: wrap; align-items: center;">
|
||||
<input type="date" name="tanggal_mulai" class="form-control" style="width: auto;" value="<?php echo e(request('tanggal_mulai')); ?>" placeholder="Tanggal Mulai">
|
||||
<input type="date" name="tanggal_selesai" class="form-control" style="width: auto;" value="<?php echo e(request('tanggal_selesai')); ?>" placeholder="Tanggal Selesai">
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index', ['bulan_ini' => 1])); ?>" class="btn btn-info btn-sm">
|
||||
<i class="fas fa-calendar-check"></i> Bulan Ini
|
||||
</a>
|
||||
</form>
|
||||
|
||||
<a href="<?php echo e(route('santri.pelanggaran.kategori')); ?>" class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-list"></i> Lihat Daftar Kategori Pelanggaran
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<?php if($riwayat->count() > 0): ?>
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">No</th>
|
||||
<th style="width: 10%;">ID Riwayat</th>
|
||||
<th style="width: 12%;">Tanggal</th>
|
||||
<th style="width: 25%;">Jenis Pelanggaran</th>
|
||||
<th style="width: 8%;">Poin</th>
|
||||
<th style="width: 30%;">Keterangan</th>
|
||||
<th style="width: 10%;" class="text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $riwayat; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($riwayat->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($item->id_riwayat); ?></strong></td>
|
||||
<td>
|
||||
<i class="fas fa-calendar"></i>
|
||||
<?php echo e(\Carbon\Carbon::parse($item->tanggal)->isoFormat('D MMM YYYY')); ?>
|
||||
|
||||
</td>
|
||||
<td><?php echo e($item->kategori->nama_pelanggaran ?? '-'); ?></td>
|
||||
<td>
|
||||
<span class="badge badge-danger badge-lg">
|
||||
<i class="fas fa-star"></i> <?php echo e($item->poin); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="content-preview">
|
||||
<?php echo e($item->keterangan ?: '-'); ?>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('santri.pelanggaran.show', $item->id)); ?>"
|
||||
class="btn btn-info btn-sm"
|
||||
title="Lihat Detail">
|
||||
<i class="fas fa-eye"></i> Detail
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($riwayat->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<h3>Tidak Ada Riwayat Pelanggaran</h3>
|
||||
<p>Selamat! Anda belum memiliki catatan pelanggaran.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/pelanggaran/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-plus-circle"></i> Tambah Kegiatan Baru</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<form action="<?php echo e(route('admin.kegiatan.store')); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="kegiatan_id">
|
||||
<i class="fas fa-hashtag form-icon"></i>
|
||||
ID Kegiatan (Otomatis)
|
||||
</label>
|
||||
<input type="text" class="form-control" value="<?php echo e($nextId); ?>" disabled>
|
||||
<small class="form-text">ID akan dibuat otomatis saat disimpan</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="kategori_id">
|
||||
<i class="fas fa-list-alt form-icon"></i>
|
||||
Kategori Kegiatan <span style="color: red;">*</span>
|
||||
</label>
|
||||
<select name="kategori_id" id="kategori_id" class="form-control <?php $__errorArgs = ['kategori_id'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Kategori --</option>
|
||||
<?php $__currentLoopData = $kategoris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $kat): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($kat->kategori_id); ?>" <?php echo e(old('kategori_id') == $kat->kategori_id ? 'selected' : ''); ?>>
|
||||
<?php echo e($kat->nama_kategori); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['kategori_id'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nama_kegiatan">
|
||||
<i class="fas fa-calendar-check form-icon"></i>
|
||||
Nama Kegiatan <span style="color: red;">*</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="nama_kegiatan"
|
||||
id="nama_kegiatan"
|
||||
class="form-control <?php $__errorArgs = ['nama_kegiatan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('nama_kegiatan')); ?>"
|
||||
placeholder="Contoh: Kajian Tafsir Al-Quran"
|
||||
required>
|
||||
<?php $__errorArgs = ['nama_kegiatan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="hari">
|
||||
<i class="fas fa-calendar-day form-icon"></i>
|
||||
Hari <span style="color: red;">*</span>
|
||||
</label>
|
||||
<select name="hari" id="hari" class="form-control <?php $__errorArgs = ['hari'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Hari --</option>
|
||||
<?php $__currentLoopData = $hariList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $h): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($h); ?>" <?php echo e(old('hari') == $h ? 'selected' : ''); ?>><?php echo e($h); ?></option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['hari'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
||||
<div class="form-group">
|
||||
<label for="waktu_mulai">
|
||||
<i class="fas fa-clock form-icon"></i>
|
||||
Waktu Mulai <span style="color: red;">*</span>
|
||||
</label>
|
||||
<input type="time"
|
||||
name="waktu_mulai"
|
||||
id="waktu_mulai"
|
||||
class="form-control <?php $__errorArgs = ['waktu_mulai'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('waktu_mulai')); ?>"
|
||||
required>
|
||||
<?php $__errorArgs = ['waktu_mulai'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="waktu_selesai">
|
||||
<i class="fas fa-clock form-icon"></i>
|
||||
Waktu Selesai <span style="color: red;">*</span>
|
||||
</label>
|
||||
<input type="time"
|
||||
name="waktu_selesai"
|
||||
id="waktu_selesai"
|
||||
class="form-control <?php $__errorArgs = ['waktu_selesai'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('waktu_selesai')); ?>"
|
||||
required>
|
||||
<?php $__errorArgs = ['waktu_selesai'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="materi">
|
||||
<i class="fas fa-book form-icon"></i>
|
||||
Materi/Topik
|
||||
</label>
|
||||
<input type="text"
|
||||
name="materi"
|
||||
id="materi"
|
||||
class="form-control <?php $__errorArgs = ['materi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('materi')); ?>"
|
||||
placeholder="Contoh: Surat Al-Baqarah Ayat 1-10">
|
||||
<?php $__errorArgs = ['materi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="keterangan">
|
||||
<i class="fas fa-align-left form-icon"></i>
|
||||
Keterangan
|
||||
</label>
|
||||
<textarea name="keterangan"
|
||||
id="keterangan"
|
||||
class="form-control <?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
rows="4"
|
||||
placeholder="Catatan tambahan tentang kegiatan ini..."><?php echo e(old('keterangan')); ?></textarea>
|
||||
<?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fas fa-save"></i> Simpan
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/data/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-id-card"></i> Daftarkan Kartu RFID</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<div class="info-box" style="margin-bottom: 25px;">
|
||||
<p><i class="fas fa-info-circle"></i> Tempelkan kartu RFID ke reader, UID akan otomatis terdeteksi pada kolom di bawah.</p>
|
||||
</div>
|
||||
|
||||
<form action="<?php echo e(route('admin.kartu-rfid.simpan', $santri->id_santri)); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label><i class="fas fa-user form-icon"></i> Data Santri</label>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Santri</th>
|
||||
<td><strong><?php echo e($santri->id_santri); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nama Lengkap</th>
|
||||
<td><?php echo e($santri->nama_lengkap); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kelas</th>
|
||||
<td><span class="badge badge-secondary"><?php echo e($santri->kelas); ?></span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="rfid_uid">
|
||||
<i class="fas fa-barcode form-icon"></i>
|
||||
UID RFID <span style="color: red;">*</span>
|
||||
</label>
|
||||
<div style="display: flex; gap: 10px; align-items: center;">
|
||||
<input type="text"
|
||||
name="rfid_uid"
|
||||
id="rfid_uid"
|
||||
class="form-control <?php $__errorArgs = ['rfid_uid'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('rfid_uid')); ?>"
|
||||
placeholder="Tempelkan kartu ke reader..."
|
||||
required
|
||||
autofocus>
|
||||
<button type="button" class="btn btn-warning" onclick="document.getElementById('rfid_uid').value = ''; document.getElementById('rfid_uid').focus();">
|
||||
<i class="fas fa-redo"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php $__errorArgs = ['rfid_uid'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">UID akan otomatis terisi saat kartu ditempelkan ke reader.</small>
|
||||
</div>
|
||||
|
||||
<div id="scanStatus" style="padding: 15px; border-radius: var(--border-radius-sm); text-align: center; margin-bottom: 20px; display: none;"></div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fas fa-save"></i> Simpan & Daftarkan
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.kartu-rfid.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const rfidInput = document.getElementById('rfid_uid');
|
||||
const scanStatus = document.getElementById('scanStatus');
|
||||
|
||||
rfidInput.addEventListener('input', function() {
|
||||
if (this.value.length > 5) {
|
||||
scanStatus.style.display = 'block';
|
||||
scanStatus.style.background = 'linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%)';
|
||||
scanStatus.style.color = 'var(--success-color)';
|
||||
scanStatus.innerHTML = '<i class="fas fa-check-circle"></i> RFID Terdeteksi: <strong>' + this.value + '</strong>';
|
||||
} else {
|
||||
scanStatus.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-focus ke input
|
||||
setInterval(() => {
|
||||
if (document.activeElement !== rfidInput) {
|
||||
rfidInput.focus();
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/kartu/daftar.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Transaksi Uang Saku'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-file-invoice"></i> Detail Transaksi Uang Saku</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<h3><i class="fas fa-receipt"></i> Informasi Transaksi</h3>
|
||||
<p class="text-muted">Detail lengkap transaksi uang saku</p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-info-circle"></i> Data Transaksi</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-hashtag"></i> ID Transaksi</th>
|
||||
<td><strong><?php echo e($transaksi->id_uang_saku); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar"></i> Tanggal Transaksi</th>
|
||||
<td><?php echo e(\Carbon\Carbon::parse($transaksi->tanggal_transaksi)->isoFormat('dddd, D MMMM YYYY')); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-exchange-alt"></i> Jenis Transaksi</th>
|
||||
<td>
|
||||
<?php if($transaksi->jenis_transaksi === 'pemasukan'): ?>
|
||||
<span class="badge badge-lg badge-success">
|
||||
<i class="fas fa-arrow-down"></i> Pemasukan
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-lg badge-danger">
|
||||
<i class="fas fa-arrow-up"></i> Pengeluaran
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-money-bill-wave"></i> Nominal</th>
|
||||
<td>
|
||||
<span style="font-size: 1.3rem; font-weight: 700; color: <?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'var(--success-color)' : 'var(--danger-color)'); ?>">
|
||||
<?php echo e('Rp ' . number_format($transaksi->nominal, 0, ',', '.')); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-wallet"></i> Saldo Sebelum</th>
|
||||
<td><?php echo e('Rp ' . number_format($transaksi->saldo_sebelum, 0, ',', '.')); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-wallet"></i> Saldo Sesudah</th>
|
||||
<td>
|
||||
<strong style="color: var(--primary-color); font-size: 1.1rem;">
|
||||
<?php echo e('Rp ' . number_format($transaksi->saldo_sesudah, 0, ',', '.')); ?>
|
||||
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-sticky-note"></i> Keterangan</th>
|
||||
<td><?php echo e($transaksi->keterangan ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-clock"></i> Dicatat Pada</th>
|
||||
<td><?php echo e($transaksi->created_at->format('d/m/Y H:i:s')); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-user-graduate"></i> Data Santri</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-id-card"></i> ID Santri</th>
|
||||
<td><?php echo e($transaksi->santri->id_santri); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-user"></i> Nama Lengkap</th>
|
||||
<td><?php echo e($transaksi->santri->nama_lengkap); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-chalkboard-teacher"></i> Kelas</th>
|
||||
<td><?php echo e($transaksi->santri->kelas); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-chart-line"></i> Visualisasi Transaksi</h4>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
|
||||
|
||||
<div style="background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); padding: 20px; border-radius: 12px; text-align: center;">
|
||||
<i class="fas fa-arrow-down" style="font-size: 2rem; color: var(--success-color); margin-bottom: 10px;"></i>
|
||||
<h5 style="margin: 0 0 5px 0; color: var(--text-light); font-size: 0.9rem;">Nominal Pemasukan</h5>
|
||||
<p style="font-size: 1.5rem; font-weight: 700; color: var(--success-color); margin: 0;">
|
||||
<?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'Rp ' . number_format($transaksi->nominal, 0, ',', '.') : 'Rp 0'); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="background: linear-gradient(135deg, #FFE8EA 0%, #FFD5D8 100%); padding: 20px; border-radius: 12px; text-align: center;">
|
||||
<i class="fas fa-arrow-up" style="font-size: 2rem; color: var(--danger-color); margin-bottom: 10px;"></i>
|
||||
<h5 style="margin: 0 0 5px 0; color: var(--text-light); font-size: 0.9rem;">Nominal Pengeluaran</h5>
|
||||
<p style="font-size: 1.5rem; font-weight: 700; color: var(--danger-color); margin: 0;">
|
||||
<?php echo e($transaksi->jenis_transaksi === 'pengeluaran' ? 'Rp ' . number_format($transaksi->nominal, 0, ',', '.') : 'Rp 0'); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="background: white; padding: 20px; border-radius: 12px; border: 2px solid var(--primary-light);">
|
||||
<h5 style="margin: 0 0 15px 0; color: var(--text-color); font-size: 1rem;">
|
||||
<i class="fas fa-wallet"></i> Perubahan Saldo
|
||||
</h5>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
|
||||
<span style="font-size: 0.9rem; color: var(--text-light);">Saldo Sebelum</span>
|
||||
<strong style="color: var(--text-color);"><?php echo e('Rp ' . number_format($transaksi->saldo_sebelum, 0, ',', '.')); ?></strong>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$maxSaldo = max($transaksi->saldo_sebelum, $transaksi->saldo_sesudah);
|
||||
$persentaseSebelum = $maxSaldo > 0 ? ($transaksi->saldo_sebelum / $maxSaldo) * 100 : 0;
|
||||
$persentaseSesudah = $maxSaldo > 0 ? ($transaksi->saldo_sesudah / $maxSaldo) * 100 : 0;
|
||||
?>
|
||||
|
||||
<div style="position: relative; height: 40px; background: #e0e0e0; border-radius: 20px; overflow: hidden; margin-bottom: 10px;">
|
||||
<div style="position: absolute; height: 100%; background: linear-gradient(90deg, var(--primary-color), var(--primary-dark)); width: <?php echo e($persentaseSebelum); ?>%; border-radius: 20px; display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 0.85rem;">
|
||||
<?php if($persentaseSebelum > 15): ?>
|
||||
<?php echo e(number_format($persentaseSebelum, 0)); ?>%
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center; margin: 15px 0;">
|
||||
<i class="fas fa-arrow-<?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'up' : 'down'); ?>"
|
||||
style="font-size: 1.5rem; color: <?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'var(--success-color)' : 'var(--danger-color)'); ?>;"></i>
|
||||
<p style="margin: 5px 0 0 0; font-size: 0.85rem; color: var(--text-light);">
|
||||
<?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'Bertambah' : 'Berkurang'); ?>
|
||||
<strong><?php echo e('Rp ' . number_format(abs($transaksi->saldo_sesudah - $transaksi->saldo_sebelum), 0, ',', '.')); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="position: relative; height: 40px; background: #e0e0e0; border-radius: 20px; overflow: hidden; margin-bottom: 10px;">
|
||||
<div style="position: absolute; height: 100%; background: linear-gradient(90deg, <?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'var(--success-color)' : 'var(--danger-color)'); ?>, <?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? '#4CAF50' : '#E77580'); ?>); width: <?php echo e($persentaseSesudah); ?>%; border-radius: 20px; display: flex; align-items: center; justify-content: center; color: white; font-weight: 600; font-size: 0.85rem;">
|
||||
<?php if($persentaseSesudah > 15): ?>
|
||||
<?php echo e(number_format($persentaseSesudah, 0)); ?>%
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<span style="font-size: 0.9rem; color: var(--text-light);">Saldo Sesudah</span>
|
||||
<strong style="color: <?php echo e($transaksi->jenis_transaksi === 'pemasukan' ? 'var(--success-color)' : 'var(--danger-color)'); ?>; font-size: 1.1rem;">
|
||||
<?php echo e('Rp ' . number_format($transaksi->saldo_sesudah, 0, ',', '.')); ?>
|
||||
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding-top: 20px; border-top: 2px solid var(--primary-light); text-align: center;">
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-list"></i> Lihat Semua Riwayat
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/uang-saku/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,295 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Riwayat Pelanggaran'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-info-circle"></i> Detail Riwayat Pelanggaran</h2>
|
||||
</div>
|
||||
|
||||
<!-- Breadcrumb -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<nav style="display: flex; align-items: center; gap: 8px; color: var(--text-light); font-size: 0.9em;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>" style="color: var(--primary-color); text-decoration: none;">
|
||||
<i class="fas fa-history"></i> Riwayat Pelanggaran
|
||||
</a>
|
||||
<i class="fas fa-chevron-right" style="font-size: 0.7em;"></i>
|
||||
<span>Detail</span>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 30px;">
|
||||
<!-- Detail Riwayat -->
|
||||
<div>
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<h3><i class="fas fa-clipboard-list"></i> Informasi Riwayat</h3>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.edit', $riwayatPelanggaran)); ?>" class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-tag"></i> ID Riwayat</th>
|
||||
<td>
|
||||
<span class="badge badge-secondary" style="font-size: 1em;">
|
||||
<?php echo e($riwayatPelanggaran->id_riwayat); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar"></i> Tanggal Pelanggaran</th>
|
||||
<td>
|
||||
<strong style="font-size: 1.1em;">
|
||||
<?php echo e(\Carbon\Carbon::parse($riwayatPelanggaran->tanggal)->isoFormat('dddd, D MMMM YYYY')); ?>
|
||||
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-fire"></i> Poin Pelanggaran</th>
|
||||
<td>
|
||||
<span class="badge badge-danger" style="font-size: 1.2em; padding: 10px 20px;">
|
||||
<i class="fas fa-star"></i> <?php echo e($riwayatPelanggaran->poin); ?> Poin
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-plus"></i> Tanggal Dicatat</th>
|
||||
<td><?php echo e($riwayatPelanggaran->created_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-check"></i> Terakhir Diperbarui</th>
|
||||
<td><?php echo e($riwayatPelanggaran->updated_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Data Santri -->
|
||||
<div class="content-box" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-color);">
|
||||
<i class="fas fa-user"></i> Data Santri
|
||||
</h3>
|
||||
|
||||
<?php if($riwayatPelanggaran->santri): ?>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-id-card"></i> ID Santri</th>
|
||||
<td>
|
||||
<span class="badge badge-primary"><?php echo e($riwayatPelanggaran->santri->id_santri); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-user"></i> Nama Lengkap</th>
|
||||
<td>
|
||||
<strong style="font-size: 1.1em;"><?php echo e($riwayatPelanggaran->santri->nama_lengkap); ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-graduation-cap"></i> Kelas</th>
|
||||
<td><?php echo e($riwayatPelanggaran->santri->kelas); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-hashtag"></i> NIS</th>
|
||||
<td><?php echo e($riwayatPelanggaran->santri->nis); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-chart-line"></i> Total Poin Pelanggaran</th>
|
||||
<td>
|
||||
<span class="badge badge-danger" style="font-size: 1em;">
|
||||
<?php echo e($riwayatPelanggaran->santri->total_poin_pelanggaran); ?> Poin
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<a href="<?php echo e(route('admin.santri.show', $riwayatPelanggaran->santri)); ?>" class="btn btn-primary" style="width: 100%;">
|
||||
<i class="fas fa-eye"></i> Lihat Detail Santri
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="text-align: center; padding: 30px; color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-triangle" style="font-size: 3em; margin-bottom: 15px;"></i>
|
||||
<p>Data santri tidak ditemukan</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Kategori Pelanggaran -->
|
||||
<div class="content-box" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-color);">
|
||||
<i class="fas fa-tags"></i> Kategori Pelanggaran
|
||||
</h3>
|
||||
|
||||
<?php if($riwayatPelanggaran->kategori): ?>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-tag"></i> ID Kategori</th>
|
||||
<td>
|
||||
<span class="badge badge-primary"><?php echo e($riwayatPelanggaran->kategori->id_kategori); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-exclamation-triangle"></i> Nama Pelanggaran</th>
|
||||
<td>
|
||||
<strong style="font-size: 1.1em;"><?php echo e($riwayatPelanggaran->kategori->nama_pelanggaran); ?></strong>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-star"></i> Poin Kategori</th>
|
||||
<td>
|
||||
<span class="badge badge-danger" style="font-size: 1em;">
|
||||
<?php echo e($riwayatPelanggaran->kategori->poin); ?> Poin
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 15px;">
|
||||
<a href="<?php echo e(route('admin.kategori-pelanggaran.show', $riwayatPelanggaran->kategori)); ?>" class="btn btn-primary" style="width: 100%;">
|
||||
<i class="fas fa-eye"></i> Lihat Detail Kategori
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="text-align: center; padding: 30px; color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-triangle" style="font-size: 3em; margin-bottom: 15px;"></i>
|
||||
<p>Kategori tidak ditemukan</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Keterangan -->
|
||||
<?php if($riwayatPelanggaran->keterangan): ?>
|
||||
<div class="content-box" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 15px; color: var(--primary-color);">
|
||||
<i class="fas fa-comment"></i> Keterangan Tambahan
|
||||
</h3>
|
||||
<div style="background: var(--bg-color); padding: 15px; border-radius: var(--border-radius-sm); border-left: 4px solid var(--primary-color);">
|
||||
<p style="margin: 0; line-height: 1.6;"><?php echo e($riwayatPelanggaran->keterangan); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Riwayat Pelanggaran Lainnya -->
|
||||
<?php if($riwayatLainnya->isNotEmpty()): ?>
|
||||
<div class="content-box" style="margin-top: 30px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-color);">
|
||||
<i class="fas fa-history"></i> Riwayat Pelanggaran Lainnya (Santri yang Sama)
|
||||
</h3>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">No</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Kategori</th>
|
||||
<th style="text-align: center;">Poin</th>
|
||||
<th style="width: 100px; text-align: center;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $riwayatLainnya; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $riwayat): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($index + 1); ?></td>
|
||||
<td><?php echo e(\Carbon\Carbon::parse($riwayat->tanggal)->format('d M Y')); ?></td>
|
||||
<td>
|
||||
<?php if($riwayat->kategori): ?>
|
||||
<strong><?php echo e($riwayat->kategori->nama_pelanggaran); ?></strong>
|
||||
<?php else: ?>
|
||||
<span style="color: var(--danger-color);">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<span class="badge badge-danger"><?php echo e($riwayat->poin); ?></span>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.show', $riwayat)); ?>" class="btn btn-sm btn-success">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="text-align: center; margin-top: 15px;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>?id_santri=<?php echo e($riwayatPelanggaran->id_santri); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-list"></i> Lihat Semua Riwayat Santri Ini
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div>
|
||||
<!-- Quick Actions -->
|
||||
<div class="card card-primary">
|
||||
<h3 style="margin-bottom: 15px;">
|
||||
<i class="fas fa-bolt"></i> Aksi Cepat
|
||||
</h3>
|
||||
<div style="display: flex; flex-direction: column; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.edit', $riwayatPelanggaran)); ?>" class="btn btn-warning" style="width: 100%;">
|
||||
<i class="fas fa-edit"></i> Edit Riwayat
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.create')); ?>" class="btn btn-primary" style="width: 100%;">
|
||||
<i class="fas fa-plus"></i> Tambah Riwayat Baru
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>" class="btn btn-secondary" style="width: 100%;">
|
||||
<i class="fas fa-list"></i> Semua Riwayat
|
||||
</a>
|
||||
|
||||
<?php if($riwayatPelanggaran->santri): ?>
|
||||
<a href="<?php echo e(route('admin.santri.show', $riwayatPelanggaran->santri)); ?>" class="btn btn-success" style="width: 100%;">
|
||||
<i class="fas fa-user"></i> Lihat Santri
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistik Poin -->
|
||||
<div class="card card-danger" style="margin-top: 20px;">
|
||||
<h3 style="margin-bottom: 15px;">
|
||||
<i class="fas fa-fire"></i> Poin Pelanggaran
|
||||
</h3>
|
||||
<div style="text-align: center;">
|
||||
<div class="card-value" style="color: var(--danger-color);"><?php echo e($riwayatPelanggaran->poin); ?></div>
|
||||
<p style="margin: 0; color: var(--text-light);">Poin Pelanggaran Ini</p>
|
||||
</div>
|
||||
|
||||
<?php if($riwayatPelanggaran->santri): ?>
|
||||
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid rgba(255, 139, 148, 0.3);">
|
||||
<div style="text-align: center;">
|
||||
<div class="card-value-small" style="color: var(--danger-color);">
|
||||
<?php echo e($riwayatPelanggaran->santri->total_poin_pelanggaran); ?>
|
||||
|
||||
</div>
|
||||
<p style="margin: 0; color: var(--text-light);">Total Poin Santri</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Info Box -->
|
||||
<div class="card card-info" style="margin-top: 20px;">
|
||||
<h3 style="margin-bottom: 10px;">
|
||||
<i class="fas fa-info-circle"></i> Informasi
|
||||
</h3>
|
||||
<p style="font-size: 0.9em; line-height: 1.6; margin: 0; color: var(--text-color);">
|
||||
Riwayat ini dicatat pada <strong><?php echo e($riwayatPelanggaran->created_at->format('d F Y')); ?></strong>
|
||||
untuk pelanggaran yang terjadi pada <strong><?php echo e(\Carbon\Carbon::parse($riwayatPelanggaran->tanggal)->format('d F Y')); ?></strong>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/riwayat_pelanggaran/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,185 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Kepulangan'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<h3>Detail Izin Kepulangan</h3>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
ID: <strong><?php echo e($kepulangan->id_kepulangan); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
<a href="<?php echo e(route('santri.kepulangan.index')); ?>" class="btn btn-secondary btn-sm hover-lift">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr style="border: none; border-top: 2px solid var(--primary-light); margin: 20px 0;">
|
||||
|
||||
|
||||
<div style="text-align: center; margin: 20px 0;">
|
||||
<span class="badge badge-<?php echo e($kepulangan->status == 'Menunggu' ? 'warning' :
|
||||
($kepulangan->status == 'Disetujui' ? 'success' :
|
||||
($kepulangan->status == 'Ditolak' ? 'danger' : 'secondary'))); ?> badge-lg">
|
||||
<i class="fas
|
||||
<?php if($kepulangan->status == 'Menunggu'): ?> fa-clock
|
||||
<?php elseif($kepulangan->status == 'Disetujui'): ?> fa-check-circle
|
||||
<?php elseif($kepulangan->status == 'Ditolak'): ?> fa-times-circle
|
||||
<?php else: ?> fa-flag-checkered <?php endif; ?>
|
||||
"></i>
|
||||
Status: <?php echo e($kepulangan->status); ?>
|
||||
|
||||
</span>
|
||||
|
||||
<?php if($kepulangan->status == 'Disetujui' && $kepulangan->is_aktif): ?>
|
||||
<span class="badge badge-info badge-lg" style="margin-left: 10px;">
|
||||
<i class="fas fa-home"></i> Sedang Dalam Periode Pulang
|
||||
</span>
|
||||
<?php elseif($kepulangan->status == 'Disetujui' && $kepulangan->is_terlambat): ?>
|
||||
<span class="badge badge-danger badge-lg" style="margin-left: 10px;">
|
||||
<i class="fas fa-exclamation-triangle"></i> Terlambat Kembali
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-code"></i> ID Kepulangan</th>
|
||||
<td><?php echo e($kepulangan->id_kepulangan); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-plus"></i> Tanggal Pengajuan</th>
|
||||
<td><?php echo e($kepulangan->tanggal_izin_formatted); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-alt"></i> Tanggal Pulang</th>
|
||||
<td><strong style="color: var(--primary-color);"><?php echo e($kepulangan->tanggal_pulang_formatted); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-check"></i> Tanggal Kembali</th>
|
||||
<td><strong style="color: var(--primary-color);"><?php echo e($kepulangan->tanggal_kembali_formatted); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-clock"></i> Durasi Izin</th>
|
||||
<td>
|
||||
<span class="badge badge-info"><?php echo e($kepulangan->durasi_izin); ?> hari</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-comment-alt"></i> Alasan Kepulangan</th>
|
||||
<td><strong><?php echo e($kepulangan->alasan); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-info-circle"></i> Status</th>
|
||||
<td>
|
||||
<span class="badge badge-<?php echo e($kepulangan->status == 'Menunggu' ? 'warning' :
|
||||
($kepulangan->status == 'Disetujui' ? 'success' :
|
||||
($kepulangan->status == 'Ditolak' ? 'danger' : 'secondary'))); ?>">
|
||||
<?php echo e($kepulangan->status); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if($kepulangan->approved_by): ?>
|
||||
<tr>
|
||||
<th><i class="fas fa-user-check"></i> Disetujui Oleh</th>
|
||||
<td><?php echo e($kepulangan->approved_by); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-check"></i> Tanggal Persetujuan</th>
|
||||
<td><?php echo e($kepulangan->approved_at_formatted); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php if($kepulangan->catatan): ?>
|
||||
<tr>
|
||||
<th><i class="fas fa-sticky-note"></i> Catatan Admin</th>
|
||||
<td style="white-space: pre-wrap;"><?php echo e($kepulangan->catatan); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="margin-top: 25px; padding: 20px; background: linear-gradient(135deg, #E3F2FD, #D1E9F9); border-radius: var(--border-radius-sm); border-left: 4px solid var(--info-color);">
|
||||
<h4 style="margin: 0 0 10px 0; color: var(--info-color);">
|
||||
<i class="fas fa-chart-bar"></i> Informasi Kuota Tahun <?php echo e(date('Y')); ?>
|
||||
|
||||
</h4>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px;">
|
||||
<div>
|
||||
<p style="margin: 0; font-size: 0.85rem; color: var(--text-light);">Total Hari Pulang</p>
|
||||
<p style="margin: 5px 0 0 0; font-size: 1.3rem; font-weight: 700; color: var(--primary-color);">
|
||||
<?php echo e($totalHariTahunIni); ?> hari
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 0; font-size: 0.85rem; color: var(--text-light);">Sisa Kuota</p>
|
||||
<p style="margin: 5px 0 0 0; font-size: 1.3rem; font-weight: 700;color: <?php echo e($sisaKuota > 0 ? 'var(--success-color)' : 'var(--danger-color)'); ?>;">
|
||||
<?php echo e($sisaKuota); ?> hari
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p style="margin: 0; font-size: 0.85rem; color: var(--text-light);">Kuota Maksimal</p>
|
||||
<p style="margin: 5px 0 0 0; font-size: 1.3rem; font-weight: 700; color: var(--text-color);">
|
||||
12 hari
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($kepulangan->status == 'Menunggu'): ?>
|
||||
<div class="info-box" style="margin-top: 20px; background: linear-gradient(135deg, #FFF8E1 0%, #FFF3CD 100%); border-color: var(--warning-color);">
|
||||
<i class="fas fa-clock"></i>
|
||||
<strong>Menunggu Persetujuan:</strong> Izin kepulangan Anda sedang dalam proses review.
|
||||
Mohon tunggu konfirmasi dari pengurus.
|
||||
</div>
|
||||
<?php elseif($kepulangan->status == 'Disetujui'): ?>
|
||||
<?php if($kepulangan->is_aktif): ?>
|
||||
<div class="info-box" style="margin-top: 20px; background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); border-color: var(--info-color);">
|
||||
<i class="fas fa-home"></i>
|
||||
<strong>Sedang Pulang:</strong> Anda sedang dalam periode kepulangan.
|
||||
Pastikan kembali sesuai jadwal: <strong><?php echo e($kepulangan->tanggal_kembali_formatted); ?></strong>.
|
||||
</div>
|
||||
<?php elseif($kepulangan->is_terlambat): ?>
|
||||
<div class="alert alert-danger" style="margin-top: 20px;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Terlambat Kembali:</strong> Anda telah melewati tanggal kembali yang dijadwalkan.
|
||||
Segera hubungi pengurus!
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="info-box" style="margin-top: 20px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border-color: var(--success-color);">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<strong>Izin Disetujui:</strong> Kepulangan Anda telah disetujui.
|
||||
Pastikan untuk pulang dan kembali sesuai jadwal yang telah ditentukan.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php elseif($kepulangan->status == 'Ditolak'): ?>
|
||||
<div class="alert alert-danger" style="margin-top: 20px;">
|
||||
<i class="fas fa-times-circle"></i>
|
||||
<strong>Izin Ditolak:</strong> Maaf, izin kepulangan Anda tidak disetujui.
|
||||
<?php if($kepulangan->catatan): ?>
|
||||
Alasan: <strong><?php echo e($kepulangan->catatan); ?></strong>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php elseif($kepulangan->status == 'Selesai'): ?>
|
||||
<div class="info-box" style="margin-top: 20px; background: linear-gradient(135deg, #E2E3E5 0%, #D6D8DB 100%); border-color: var(--text-light);">
|
||||
<i class="fas fa-flag-checkered"></i>
|
||||
<strong>Kepulangan Selesai:</strong> Anda telah menyelesaikan periode kepulangan ini.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div style="margin-top: 20px; text-align: center;">
|
||||
<a href="<?php echo e(route('santri.kepulangan.index')); ?>" class="btn btn-primary hover-lift">
|
||||
<i class="fas fa-list"></i> Lihat Semua Riwayat
|
||||
</a>
|
||||
<a href="<?php echo e(route('santri.dashboard')); ?>" class="btn btn-secondary hover-lift">
|
||||
<i class="fas fa-home"></i> Kembali ke Dashboard
|
||||
</a>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/kepulangan/show.blade.php ENDPATH**/ ?>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,134 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Riwayat Uang Saku'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-wallet"></i> Riwayat Uang Saku</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(session('error')): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php echo e(session('error')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-arrow-down"></i> Total Pemasukan</h3>
|
||||
<div class="card-value"><?php echo e('Rp ' . number_format($totalPemasukan, 0, ',', '.')); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-arrow-down"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="card card-danger">
|
||||
<h3><i class="fas fa-arrow-up"></i> Total Pengeluaran</h3>
|
||||
<div class="card-value"><?php echo e('Rp ' . number_format($totalPengeluaran, 0, ',', '.')); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-arrow-up"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<h3><i class="fas fa-wallet"></i> Saldo Terakhir</h3>
|
||||
<div class="card-value"><?php echo e('Rp ' . number_format($saldoTerakhir, 0, ',', '.')); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-wallet"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<form method="GET" action="<?php echo e(route('santri.uang-saku.index')); ?>" class="filter-form-inline">
|
||||
<input type="text" name="search" class="form-control" placeholder="Cari keterangan..." value="<?php echo e(request('search')); ?>" style="min-width: 200px;">
|
||||
|
||||
<select name="jenis_transaksi" class="form-control" style="min-width: 150px;">
|
||||
<option value="">Semua Jenis</option>
|
||||
<option value="pemasukan" <?php echo e(request('jenis_transaksi') == 'pemasukan' ? 'selected' : ''); ?>>Pemasukan</option>
|
||||
<option value="pengeluaran" <?php echo e(request('jenis_transaksi') == 'pengeluaran' ? 'selected' : ''); ?>>Pengeluaran</option>
|
||||
</select>
|
||||
|
||||
<input type="date" name="tanggal_dari" class="form-control" value="<?php echo e(request('tanggal_dari')); ?>" placeholder="Dari Tanggal">
|
||||
|
||||
<input type="date" name="tanggal_sampai" class="form-control" value="<?php echo e(request('tanggal_sampai')); ?>" placeholder="Sampai Tanggal">
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="table-container" style="margin-top: 20px;">
|
||||
<?php if($riwayatUangSaku->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>ID Transaksi</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Jenis</th>
|
||||
<th>Nominal</th>
|
||||
<th>Keterangan</th>
|
||||
<th>Saldo Sebelum</th>
|
||||
<th>Saldo Sesudah</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $riwayatUangSaku; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $transaksi): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($riwayatUangSaku->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($transaksi->id_uang_saku); ?></strong></td>
|
||||
<td><?php echo e(\Carbon\Carbon::parse($transaksi->tanggal_transaksi)->format('d/m/Y')); ?></td>
|
||||
<td>
|
||||
<?php if($transaksi->jenis_transaksi === 'pemasukan'): ?>
|
||||
<span class="badge badge-success">
|
||||
<i class="fas fa-arrow-down"></i> Pemasukan
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-danger">
|
||||
<i class="fas fa-arrow-up"></i> Pengeluaran
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="nominal-highlight"><?php echo e('Rp ' . number_format($transaksi->nominal, 0, ',', '.')); ?></td>
|
||||
<td><?php echo e($transaksi->keterangan ?? '-'); ?></td>
|
||||
<td><?php echo e('Rp ' . number_format($transaksi->saldo_sebelum, 0, ',', '.')); ?></td>
|
||||
<td><?php echo e('Rp ' . number_format($transaksi->saldo_sesudah, 0, ',', '.')); ?></td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('santri.uang-saku.show', $transaksi->id)); ?>" class="btn btn-sm btn-primary" title="Lihat Detail">
|
||||
<i class="fas fa-eye"></i> Detail
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($riwayatUangSaku->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox"></i>
|
||||
<h3>Belum Ada Transaksi</h3>
|
||||
<p>Riwayat uang saku Anda masih kosong.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/uang-saku/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Berita - ' . $berita->id_berita); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-newspaper"></i> Detail Berita</h2>
|
||||
</div>
|
||||
|
||||
<!-- Header Actions -->
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;">
|
||||
<div>
|
||||
<span class="badge <?php echo e($berita->status_badge); ?>" style="font-size: 1em; padding: 8px 15px;">
|
||||
<?php if($berita->status === 'published'): ?>
|
||||
<i class="fas fa-check-circle"></i> Published
|
||||
<?php else: ?>
|
||||
<i class="fas fa-edit"></i> Draft
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.berita.edit', $berita->id_berita)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.berita.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Detail Berita -->
|
||||
<div class="content-box">
|
||||
<div style="padding: 10px;">
|
||||
<!-- Header Berita -->
|
||||
<div style="border-bottom: 3px solid var(--primary-color); padding-bottom: 25px; margin-bottom: 30px;">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<span style="background: var(--primary-light); color: var(--primary-dark); padding: 6px 12px; border-radius: var(--border-radius-sm); font-weight: 600; font-size: 0.9em;">
|
||||
ID: <?php echo e($berita->id_berita); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 style="color: var(--primary-dark); margin-bottom: 20px; font-size: 2em; line-height: 1.3;">
|
||||
<?php echo e($berita->judul); ?>
|
||||
|
||||
</h1>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 20px; align-items: center; color: var(--text-light); font-size: 0.95em;">
|
||||
<span>
|
||||
<i class="fas fa-user"></i>
|
||||
<strong>Penulis:</strong> <?php echo e($berita->penulis); ?>
|
||||
|
||||
</span>
|
||||
<span>
|
||||
<i class="fas fa-calendar"></i>
|
||||
<strong>Tanggal:</strong> <?php echo e($berita->created_at->format('d M Y, H:i')); ?> WIB
|
||||
</span>
|
||||
<span>
|
||||
<?php
|
||||
$badgeClass = match($berita->target_berita) {
|
||||
'semua' => 'badge-primary',
|
||||
'kelas_tertentu' => 'badge-info',
|
||||
'santri_tertentu' => 'badge-warning',
|
||||
default => 'badge-secondary'
|
||||
};
|
||||
?>
|
||||
<span class="badge <?php echo e($badgeClass); ?>">
|
||||
<i class="fas fa-bullseye"></i> <?php echo e($berita->target_audience); ?>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gambar Berita -->
|
||||
<?php if($berita->gambar): ?>
|
||||
<div style="text-align: center; margin: 40px 0;">
|
||||
<img src="<?php echo e(asset('storage/' . $berita->gambar)); ?>"
|
||||
alt="Gambar Berita"
|
||||
style="max-width: 100%; max-height: 500px; border-radius: var(--border-radius); box-shadow: var(--shadow-lg); object-fit: cover;">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Konten Berita -->
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-align-left"></i> Konten Berita</h4>
|
||||
<div style="line-height: 1.9; font-size: 1.05em; color: var(--text-color); background: var(--primary-light); padding: 25px; border-radius: var(--border-radius-sm); border-left: 4px solid var(--primary-color);">
|
||||
<?php echo nl2br(e($berita->konten)); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Info Target Santri -->
|
||||
<?php if($berita->target_berita === 'santri_tertentu' || $berita->target_berita === 'kelas_tertentu'): ?>
|
||||
<div class="detail-section">
|
||||
<?php if($berita->target_berita === 'kelas_tertentu'): ?>
|
||||
<h4>
|
||||
<i class="fas fa-graduation-cap"></i>
|
||||
Target Kelas: <?php echo e(implode(', ', $berita->target_kelas ?? [])); ?>
|
||||
|
||||
</h4>
|
||||
<div style="background: var(--info-color); background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); padding: 20px; border-radius: var(--border-radius-sm); border-left: 4px solid var(--info-color);">
|
||||
<p style="margin: 0; color: var(--text-color); font-size: 1em;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Berita ini ditujukan untuk santri dari kelas:
|
||||
<strong><?php echo e(implode(', ', $berita->target_kelas ?? [])); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($berita->santriTertentu->count() > 0): ?>
|
||||
<h4 style="margin-top: 25px;">
|
||||
<i class="fas fa-users"></i>
|
||||
Daftar Penerima Berita (<?php echo e($berita->santriTertentu->count()); ?> Santri)
|
||||
</h4>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 15px;">
|
||||
<?php $__currentLoopData = $berita->santriTertentu; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div style="background: white; border: 2px solid var(--primary-light); border-radius: var(--border-radius-sm); padding: 15px; transition: all 0.3s ease; box-shadow: var(--shadow-sm);">
|
||||
<div style="display: flex; align-items: center; gap: 15px;">
|
||||
<!-- Hanya tampilkan initial, tanpa foto -->
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 1.5em; flex-shrink: 0;">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="flex-grow: 1; min-width: 0;">
|
||||
<div style="font-weight: 600; color: var(--primary-color); margin-bottom: 3px;">
|
||||
<?php echo e($santri->id_santri); ?>
|
||||
|
||||
</div>
|
||||
<div style="font-weight: 600; color: var(--text-color); font-size: 1em; margin-bottom: 3px;">
|
||||
<?php echo e($santri->nama_lengkap); ?>
|
||||
|
||||
</div>
|
||||
<div style="font-size: 0.85em; color: var(--text-light);">
|
||||
<i class="fas fa-graduation-cap"></i> <?php echo e($santri->kelas); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status Baca -->
|
||||
<div style="text-align: center; flex-shrink: 0;">
|
||||
<?php if($santri->pivot->sudah_dibaca): ?>
|
||||
<span class="badge badge-success" title="Dibaca pada <?php echo e($santri->pivot->tanggal_baca); ?>">
|
||||
<i class="fas fa-check"></i> Dibaca
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-warning">
|
||||
<i class="fas fa-clock"></i> Belum
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="text-align: center; padding: 40px; background: var(--primary-light); border-radius: var(--border-radius-sm);">
|
||||
<i class="fas fa-users" style="font-size: 3em; color: #ccc; margin-bottom: 15px;"></i>
|
||||
<p style="color: var(--text-light); margin: 0;">Belum ada santri yang dipilih untuk berita ini.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Aksi -->
|
||||
<div style="border-top: 2px solid var(--primary-light); padding-top: 30px; margin-top: 40px; text-align: center;">
|
||||
<div style="display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;">
|
||||
<a href="<?php echo e(route('admin.berita.edit', $berita->id_berita)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit Berita
|
||||
</a>
|
||||
|
||||
<form action="<?php echo e(route('admin.berita.destroy', $berita->id_berita)); ?>"
|
||||
method="POST"
|
||||
style="display: inline;"
|
||||
onsubmit="return confirm('Yakin ingin menghapus berita ini? Tindakan ini tidak dapat dibatalkan!')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Hapus Berita
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a href="<?php echo e(route('admin.berita.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-list"></i> Daftar Berita
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/berita/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-book-open"></i> Detail Materi</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
|
||||
<div class="detail-header">
|
||||
<div>
|
||||
<h3><?php echo e($materi->nama_kitab); ?></h3>
|
||||
<p class="text-muted">ID: <?php echo e($materi->id_materi); ?></p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.materi.edit', $materi)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.materi.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-info-circle"></i> Informasi Materi</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-fingerprint"></i> ID Materi</th>
|
||||
<td><strong><?php echo e($materi->id_materi); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-layer-group"></i> Kategori</th>
|
||||
<td><?php echo $materi->kategori_badge; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-users"></i> Kelas</th>
|
||||
<td><?php echo $materi->kelas_badge; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-book"></i> Nama Kitab</th>
|
||||
<td><strong><?php echo e($materi->nama_kitab); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-file-alt"></i> Halaman Mulai</th>
|
||||
<td><?php echo e($materi->halaman_mulai); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-file-alt"></i> Halaman Akhir</th>
|
||||
<td><?php echo e($materi->halaman_akhir); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calculator"></i> Total Halaman</th>
|
||||
<td>
|
||||
<span class="badge badge-lg badge-primary">
|
||||
<i class="fas fa-book-open"></i> <?php echo e($materi->total_halaman); ?> Halaman
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-align-left"></i> Deskripsi</th>
|
||||
<td><?php echo e($materi->deskripsi ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-plus"></i> Dibuat Pada</th>
|
||||
<td><?php echo e($materi->created_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar-edit"></i> Terakhir Diupdate</th>
|
||||
<td><?php echo e($materi->updated_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-chart-bar"></i> Statistik Capaian</h4>
|
||||
<div class="info-box">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<p style="margin: 0;">
|
||||
Fitur statistik capaian santri akan tersedia setelah implementasi <strong>Langkah 2: Input Capaian per Santri</strong>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 30px; display: flex; gap: 10px; justify-content: flex-end;">
|
||||
<a href="<?php echo e(route('admin.materi.edit', $materi)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit Materi
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.materi.destroy', $materi)); ?>" method="POST" style="display: inline-block;"
|
||||
onsubmit="return confirm('Yakin ingin menghapus materi <?php echo e($materi->nama_kitab); ?>? Data capaian santri yang terkait juga akan terhapus!')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Hapus Materi
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/materi/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php $__env->startSection('title', __('Page Expired')); ?>
|
||||
<?php $__env->startSection('code', '419'); ?>
|
||||
<?php $__env->startSection('message', __('Page Expired')); ?>
|
||||
|
||||
<?php echo $__env->make('errors::minimal', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions/views/419.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-id-card"></i> Kelola Kartu RFID Santri</h2>
|
||||
</div>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(session('error')): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php echo e(session('error')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content-box">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<form method="GET" class="filter-form-inline">
|
||||
<select name="filter" class="form-control">
|
||||
<option value="">-- Semua Santri --</option>
|
||||
<option value="ada_rfid" <?php echo e(request('filter') == 'ada_rfid' ? 'selected' : ''); ?>>Sudah Punya RFID</option>
|
||||
<option value="belum_rfid" <?php echo e(request('filter') == 'belum_rfid' ? 'selected' : ''); ?>>Belum Punya RFID</option>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
|
||||
<?php if(request('filter')): ?>
|
||||
<a href="<?php echo e(route('admin.kartu-rfid.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i> Reset
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if($santris->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">No</th>
|
||||
<th style="width: 100px;">ID Santri</th>
|
||||
<th>Nama Santri</th>
|
||||
<th style="width: 100px;">Kelas</th>
|
||||
<th style="width: 200px;">UID RFID</th>
|
||||
<th style="width: 120px; text-align: center;">Status</th>
|
||||
<th style="width: 250px; text-align: center;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $santris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($santris->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($santri->id_santri); ?></strong></td>
|
||||
<td><?php echo e($santri->nama_lengkap); ?></td>
|
||||
<td><span class="badge badge-secondary"><?php echo e($santri->kelas); ?></span></td>
|
||||
<td>
|
||||
<?php if($santri->rfid_uid): ?>
|
||||
<code style="font-size: 0.85rem;"><?php echo e($santri->rfid_uid); ?></code>
|
||||
<?php else: ?>
|
||||
<span style="color: var(--text-light);">-</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php if($santri->rfid_uid): ?>
|
||||
<span class="badge badge-success"><i class="fas fa-check"></i> Terdaftar</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-warning"><i class="fas fa-exclamation"></i> Belum</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<?php if($santri->rfid_uid): ?>
|
||||
<a href="<?php echo e(route('admin.kartu-rfid.cetak', $santri->id_santri)); ?>" class="btn btn-sm btn-primary" title="Cetak Kartu" target="_blank">
|
||||
<i class="fas fa-print"></i> Cetak
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.kartu-rfid.hapus', $santri->id_santri)); ?>" method="POST" style="display: inline-block;" onsubmit="return confirm('Yakin ingin menghapus RFID ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="Hapus RFID">
|
||||
<i class="fas fa-trash"></i> Hapus
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<a href="<?php echo e(route('admin.kartu-rfid.daftar', $santri->id_santri)); ?>" class="btn btn-sm btn-success" title="Daftarkan RFID">
|
||||
<i class="fas fa-id-card"></i> Daftarkan RFID
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($santris->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-users-slash"></i>
|
||||
<h3>Tidak Ada Data Santri</h3>
|
||||
<p>Belum ada santri aktif yang terdaftar.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/kartu/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Riwayat Kesehatan'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-heartbeat"></i> Riwayat Kesehatan</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
Riwayat kunjungan UKP <strong><?php echo e($santri->nama_lengkap); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Error:</strong> <?php echo e($errors->first()); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-notes-medical"></i> Total Kunjungan</h3>
|
||||
<div class="card-value"><?php echo e($statistik['total_kunjungan']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-notes-medical"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Periode yang dipilih
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-danger">
|
||||
<h3><i class="fas fa-procedures"></i> Sedang Dirawat</h3>
|
||||
<div class="card-value"><?php echo e($statistik['sedang_dirawat']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-procedures"></i></div>
|
||||
<?php if($statistik['sedang_dirawat'] > 0): ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-circle"></i> Perlu perhatian
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Tidak ada yang dirawat
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-check-circle"></i> Sembuh</h3>
|
||||
<div class="card-value"><?php echo e($statistik['sembuh']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-check-circle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Alhamdulillah
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-home"></i> Izin Sakit</h3>
|
||||
<div class="card-value"><?php echo e($statistik['izin']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-home"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Izin pulang
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<form method="GET" action="<?php echo e(route('santri.kesehatan.index')); ?>" id="filterForm">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; align-items: end;">
|
||||
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<label style="margin-bottom: 8px; display: block;">
|
||||
<i class="fas fa-calendar-alt form-icon"></i> Tanggal Dari
|
||||
</label>
|
||||
<input type="date"
|
||||
name="tanggal_dari"
|
||||
class="form-control"
|
||||
value="<?php echo e($tanggalDari->format('Y-m-d')); ?>"
|
||||
max="<?php echo e(date('Y-m-d')); ?>">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<label style="margin-bottom: 8px; display: block;">
|
||||
<i class="fas fa-calendar-check form-icon"></i> Tanggal Sampai
|
||||
</label>
|
||||
<input type="date"
|
||||
name="tanggal_sampai"
|
||||
class="form-control"
|
||||
value="<?php echo e($tanggalSampai->format('Y-m-d')); ?>"
|
||||
max="<?php echo e(date('Y-m-d')); ?>">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group" style="margin-bottom: 0;">
|
||||
<label style="margin-bottom: 8px; display: block;">
|
||||
<i class="fas fa-filter form-icon"></i> Status
|
||||
</label>
|
||||
<select name="status" class="form-control">
|
||||
<option value="">Semua Status</option>
|
||||
<?php $__currentLoopData = $statusOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $value => $label): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($value); ?>" <?php echo e(request('status') == $value ? 'selected' : ''); ?>>
|
||||
<?php echo e($label); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<button type="submit" class="btn btn-primary hover-lift" style="flex: 1;">
|
||||
<i class="fas fa-search"></i> Filter
|
||||
</button>
|
||||
<a href="<?php echo e(route('santri.kesehatan.index')); ?>" class="btn btn-secondary hover-lift" style="flex: 1;">
|
||||
<i class="fas fa-sync"></i> Reset
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<div style="margin-top: 15px; padding-top: 15px; border-top: 1px solid var(--primary-light);">
|
||||
<p style="margin: 0; color: var(--text-light); font-size: 0.9rem;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Menampilkan data periode:
|
||||
<strong style="color: var(--primary-color);">
|
||||
<?php echo e($tanggalDari->locale('id')->isoFormat('D MMMM Y')); ?> - <?php echo e($tanggalSampai->locale('id')->isoFormat('D MMMM Y')); ?>
|
||||
|
||||
</strong>
|
||||
(<?php echo e($tanggalDari->diffInDays($tanggalSampai) + 1); ?> hari)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($riwayatKesehatan->isEmpty()): ?>
|
||||
<div class="empty-state" style="margin-top: 20px;">
|
||||
<i class="fas fa-notes-medical"></i>
|
||||
<h3>Tidak Ada Data</h3>
|
||||
<p>Tidak ada riwayat kesehatan pada periode yang dipilih.</p>
|
||||
<a href="<?php echo e(route('santri.kesehatan.index')); ?>" class="btn btn-primary" style="margin-top: 15px;">
|
||||
<i class="fas fa-sync"></i> Lihat Semua Data
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h3 style="margin: 0 0 15px 0; color: var(--primary-color);">
|
||||
<i class="fas fa-list"></i> Daftar Riwayat (<?php echo e($riwayatKesehatan->total()); ?> data)
|
||||
</h3>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 15px;">
|
||||
<?php $__currentLoopData = $riwayatKesehatan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<a href="<?php echo e(route('santri.kesehatan.show', $item->id)); ?>"
|
||||
style="display: flex; gap: 15px; padding: 15px; background: linear-gradient(135deg, #FFFFFF 0%, #FEFFFE 100%); border-radius: var(--border-radius-sm); border-left: 4px solid
|
||||
<?php if($item->status == 'dirawat'): ?> var(--danger-color)
|
||||
<?php elseif($item->status == 'sembuh'): ?> var(--success-color)
|
||||
<?php else: ?> var(--warning-color) <?php endif; ?>
|
||||
; text-decoration: none; transition: var(--transition-base); position: relative;"
|
||||
onmouseover="this.style.boxShadow='var(--shadow-md)'; this.style.transform='translateX(5px)';"
|
||||
onmouseout="this.style.boxShadow='none'; this.style.transform='translateX(0)';">
|
||||
|
||||
|
||||
<div style="flex-shrink: 0; width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background:
|
||||
<?php if($item->status == 'dirawat'): ?> linear-gradient(135deg, #FFE8EA, #FFD5D8)
|
||||
<?php elseif($item->status == 'sembuh'): ?> linear-gradient(135deg, #E8F7F2, #D4F1E3)
|
||||
<?php else: ?> linear-gradient(135deg, #FFF8E1, #FFF3CD) <?php endif; ?>
|
||||
;">
|
||||
<i class="fas
|
||||
<?php if($item->status == 'dirawat'): ?> fa-procedures
|
||||
<?php elseif($item->status == 'sembuh'): ?> fa-check-circle
|
||||
<?php else: ?> fa-home <?php endif; ?>
|
||||
" style="font-size: 1.8rem; color:
|
||||
<?php if($item->status == 'dirawat'): ?> var(--danger-color)
|
||||
<?php elseif($item->status == 'sembuh'): ?> var(--success-color)
|
||||
<?php else: ?> var(--warning-color) <?php endif; ?>
|
||||
;"></i>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="flex: 1; display: flex; flex-direction: column; justify-content: space-between; min-width: 0;">
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 8px;">
|
||||
<h3 style="margin: 0; font-size: 1rem; font-weight: 600; color: var(--text-color);">
|
||||
<?php echo e($item->keluhan); ?>
|
||||
|
||||
</h3>
|
||||
<span class="badge badge-<?php echo e($item->status_badge_color); ?>">
|
||||
<?php echo e(ucfirst($item->status)); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p style="margin: 0 0 8px 0; font-size: 0.9rem; color: var(--text-light);">
|
||||
<i class="fas fa-code"></i> <?php echo e($item->id_kesehatan); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 15px; font-size: 0.85rem; color: var(--text-light);">
|
||||
<span>
|
||||
<i class="fas fa-calendar-plus"></i> Masuk: <?php echo e($item->tanggal_masuk_formatted); ?>
|
||||
|
||||
</span>
|
||||
<?php if($item->tanggal_keluar): ?>
|
||||
<span>
|
||||
<i class="fas fa-calendar-check"></i> Keluar: <?php echo e($item->tanggal_keluar_formatted); ?>
|
||||
|
||||
</span>
|
||||
<span class="badge badge-info badge-sm">
|
||||
<i class="fas fa-clock"></i> <?php echo e($item->lama_dirawat); ?> hari
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-danger badge-sm">
|
||||
<i class="fas fa-procedures"></i> Masih dirawat (<?php echo e($item->lama_dirawat); ?> hari)
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="flex-shrink: 0; display: flex; align-items: center;">
|
||||
<i class="fas fa-chevron-right" style="color: var(--text-light);"></i>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 25px;">
|
||||
<?php echo e($riwayatKesehatan->links()); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="info-box" style="margin-top: 20px;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Info:</strong> Gunakan filter tanggal untuk melihat riwayat kesehatan pada periode tertentu.
|
||||
Jika tidak difilter, data yang ditampilkan adalah untuk bulan berjalan.
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 20px; text-align: center;">
|
||||
<a href="<?php echo e(route('santri.dashboard')); ?>" class="btn btn-secondary hover-lift">
|
||||
<i class="fas fa-home"></i> Kembali ke Dashboard
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const tanggalDari = document.querySelector('input[name="tanggal_dari"]');
|
||||
const tanggalSampai = document.querySelector('input[name="tanggal_sampai"]');
|
||||
|
||||
// Validasi tanggal
|
||||
tanggalDari.addEventListener('change', function() {
|
||||
if (tanggalSampai.value && tanggalSampai.value < this.value) {
|
||||
alert('Tanggal sampai tidak boleh lebih kecil dari tanggal dari!');
|
||||
this.value = tanggalSampai.value;
|
||||
}
|
||||
});
|
||||
|
||||
tanggalSampai.addEventListener('change', function() {
|
||||
if (tanggalDari.value && this.value < tanggalDari.value) {
|
||||
alert('Tanggal sampai tidak boleh lebih kecil dari tanggal dari!');
|
||||
this.value = tanggalDari.value;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/kesehatan/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Santri: ' . $santri->nama_lengkap); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-user"></i> Detail Santri</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<div style="display: flex; align-items: center; gap: 20px;">
|
||||
|
||||
<?php if($santri->foto): ?>
|
||||
<img src="<?php echo e(asset('storage/' . $santri->foto)); ?>"
|
||||
alt="Foto <?php echo e($santri->nama_lengkap); ?>"
|
||||
style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid var(--primary-color); flex-shrink: 0;"
|
||||
loading="lazy">
|
||||
<?php else: ?>
|
||||
<div style="width: 80px; height: 80px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; font-weight: bold; flex-shrink: 0;">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div>
|
||||
<h3><?php echo e($santri->nama_lengkap); ?></h3>
|
||||
<p style="color: #7F8C8D; margin: 5px 0 0 0;">
|
||||
<i class="fas fa-id-badge"></i> <?php echo e($santri->id_santri); ?>
|
||||
|
||||
<?php if($santri->nis): ?>
|
||||
| <i class="fas fa-barcode"></i> NIS: <?php echo e($santri->nis); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.santri.edit', $santri)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.santri.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr style="border: none; border-top: 2px solid #E8F7F2; margin: 25px 0;">
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-id-card"></i> Informasi Dasar</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th width="200">ID Santri</th>
|
||||
<td><strong><?php echo e($santri->id_santri); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>NIS</th>
|
||||
<td><?php echo e($santri->nis ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nama Lengkap</th>
|
||||
<td><strong><?php echo e($santri->nama_lengkap); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Jenis Kelamin</th>
|
||||
<td>
|
||||
<?php if($santri->jenis_kelamin == 'Laki-laki'): ?>
|
||||
<i class="fas fa-mars" style="color: #81C6E8;"></i> <?php echo e($santri->jenis_kelamin); ?>
|
||||
|
||||
<?php else: ?>
|
||||
<i class="fas fa-venus" style="color: #FF8B94;"></i> <?php echo e($santri->jenis_kelamin); ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kelas</th>
|
||||
<td>
|
||||
<strong style="color: #6FBA9D; font-size: 1.1rem;"><?php echo e($santri->kelas); ?></strong>
|
||||
<?php if($santri->kelas == 'PB'): ?>
|
||||
<span style="color: #7F8C8D; font-size: 0.85rem;">(Pembinaan)</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td>
|
||||
<?php if($santri->status == 'Aktif'): ?>
|
||||
<span style="padding: 6px 12px; border-radius: 6px; font-size: 0.85rem; font-weight: 600; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); color: #2C5F4F; display: inline-block;">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e($santri->status); ?>
|
||||
|
||||
</span>
|
||||
<?php elseif($santri->status == 'Lulus'): ?>
|
||||
<span style="padding: 6px 12px; border-radius: 6px; font-size: 0.85rem; font-weight: 600; background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); color: #2D4A7C; display: inline-block;">
|
||||
<i class="fas fa-graduation-cap"></i> <?php echo e($santri->status); ?>
|
||||
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span style="padding: 6px 12px; border-radius: 6px; font-size: 0.85rem; font-weight: 600; background: linear-gradient(135deg, #E8ECF0 0%, #D1D8E0 100%); color: #555; display: inline-block;">
|
||||
<i class="fas fa-times-circle"></i> <?php echo e($santri->status); ?>
|
||||
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-map-marker-alt"></i> Alamat & Asal</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th width="200">Alamat Santri</th>
|
||||
<td><?php echo e($santri->alamat_santri ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Daerah Asal</th>
|
||||
<td>
|
||||
<?php if($santri->daerah_asal): ?>
|
||||
<i class="fas fa-map-pin" style="color: #6FBA9D;"></i> <?php echo e($santri->daerah_asal); ?>
|
||||
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-users"></i> Data Orang Tua / Wali</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th width="200">Nama Orang Tua</th>
|
||||
<td><?php echo e($santri->nama_orang_tua ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nomor HP Orang Tua</th>
|
||||
<td>
|
||||
<?php if($santri->nomor_hp_ortu): ?>
|
||||
<i class="fas fa-phone" style="color: #6FBA9D;"></i>
|
||||
<a href="tel:<?php echo e($santri->nomor_hp_ortu); ?>" style="color: #6FBA9D; text-decoration: none;">
|
||||
<?php echo e($santri->nomor_hp_ortu); ?>
|
||||
|
||||
</a>
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-clock"></i> Informasi Sistem</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th width="200">Tanggal Dibuat</th>
|
||||
<td>
|
||||
<i class="fas fa-calendar-plus" style="color: #81C6E8;"></i>
|
||||
<?php echo e($santri->created_at->format('d M Y, H:i')); ?> WIB
|
||||
<span style="color: #7F8C8D; font-size: 0.85rem;">
|
||||
(<?php echo e($santri->created_at->diffForHumans()); ?>)
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Terakhir Diupdate</th>
|
||||
<td>
|
||||
<i class="fas fa-calendar-check" style="color: #FFD56B;"></i>
|
||||
<?php echo e($santri->updated_at->format('d M Y, H:i')); ?> WIB
|
||||
<span style="color: #7F8C8D; font-size: 0.85rem;">
|
||||
(<?php echo e($santri->updated_at->diffForHumans()); ?>)
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px; padding: 20px; background: linear-gradient(135deg, #F8FBF9 0%, #E8F7F2 100%); border-radius: 8px; border-left: 4px solid #6FBA9D;">
|
||||
<p style="margin: 0; color: #2C5F4F; font-size: 0.9rem;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Informasi:</strong> Data santri ini dapat diedit atau dihapus melalui halaman index atau menggunakan tombol Edit di atas.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', ['isAdmin' => true], \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/santri/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Detail Riwayat Pelanggaran'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-file-alt"></i> Detail Riwayat Pelanggaran</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<h3>
|
||||
<i class="fas fa-exclamation-circle" style="color: var(--danger-color);"></i>
|
||||
Riwayat ID: <?php echo e($riwayatPelanggaran->id_riwayat); ?>
|
||||
|
||||
</h3>
|
||||
<div>
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-info-circle"></i> Informasi Pelanggaran</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th><i class="fas fa-hashtag"></i> ID Riwayat</th>
|
||||
<td><strong><?php echo e($riwayatPelanggaran->id_riwayat); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-calendar"></i> Tanggal Kejadian</th>
|
||||
<td><?php echo e(\Carbon\Carbon::parse($riwayatPelanggaran->tanggal)->isoFormat('dddd, D MMMM YYYY')); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-list"></i> Jenis Pelanggaran</th>
|
||||
<td><strong><?php echo e($riwayatPelanggaran->kategori->nama_pelanggaran ?? '-'); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-star"></i> Poin Pelanggaran</th>
|
||||
<td>
|
||||
<span class="badge badge-danger badge-lg">
|
||||
<i class="fas fa-star"></i> <?php echo e($riwayatPelanggaran->poin); ?> Poin
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-comment-alt"></i> Keterangan</th>
|
||||
<td><?php echo e($riwayatPelanggaran->keterangan ?: '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><i class="fas fa-clock"></i> Dicatat Pada</th>
|
||||
<td><?php echo e($riwayatPelanggaran->created_at->isoFormat('D MMMM YYYY, HH:mm')); ?> WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="info-box">
|
||||
<p>
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Catatan:</strong> Data pelanggaran ini dicatat oleh admin/pengurus pondok.
|
||||
Jika ada kesalahan data, silakan hubungi bagian administrasi.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/pelanggaran/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
<!-- resources/views/santri/profil/index.blade.php -->
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Edit Profil Santri'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-user-edit"></i> Edit Profil</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<form action="<?php echo e(route('santri.profil.update')); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('PUT'); ?>
|
||||
|
||||
|
||||
<div class="info-box" style="margin-bottom: 25px;">
|
||||
<p style="margin: 0;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Info:</strong> Anda hanya dapat mengubah alamat dan nomor HP orang tua.
|
||||
Untuk perubahan data lain, silakan hubungi admin.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<i class="fas fa-user form-icon"></i>
|
||||
Nama Lengkap
|
||||
</label>
|
||||
<input type="text" class="form-control" value="<?php echo e($santri->nama_lengkap); ?>" disabled>
|
||||
<span class="form-text">Data ini tidak dapat diubah</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="alamat_santri">
|
||||
<i class="fas fa-map-marker-alt form-icon"></i>
|
||||
Alamat Lengkap
|
||||
</label>
|
||||
<textarea
|
||||
name="alamat_santri"
|
||||
id="alamat_santri"
|
||||
class="form-control <?php $__errorArgs = ['alamat_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
rows="4"
|
||||
placeholder="Masukkan alamat lengkap (nama jalan, RT/RW, kelurahan, kecamatan, kota/kabupaten)"
|
||||
><?php echo e(old('alamat_santri', $santri->alamat_santri)); ?></textarea>
|
||||
|
||||
<?php $__errorArgs = ['alamat_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
|
||||
<span class="form-text">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
Contoh: Jl. Merdeka No. 123, RT 02/RW 05, Kel. Sukamaju, Kec. Bandung Tengah, Kota Bandung
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nomor_hp_ortu">
|
||||
<i class="fas fa-phone form-icon"></i>
|
||||
Nomor HP Orang Tua/Wali
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="nomor_hp_ortu"
|
||||
id="nomor_hp_ortu"
|
||||
class="form-control <?php $__errorArgs = ['nomor_hp_ortu'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('nomor_hp_ortu', $santri->nomor_hp_ortu)); ?>"
|
||||
placeholder="Contoh: 0812-3456-7890 atau +62812-3456-7890"
|
||||
>
|
||||
|
||||
<?php $__errorArgs = ['nomor_hp_ortu'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
|
||||
<span class="form-text">
|
||||
<i class="fas fa-lightbulb"></i>
|
||||
Format: 08XX-XXXX-XXXX atau +628XX-XXXX-XXXX
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="btn-group" style="margin-top: 30px;">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fas fa-save"></i> Simpan Perubahan
|
||||
</button>
|
||||
<a href="<?php echo e(route('santri.profil.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i> Batal
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const nomorHpInput = document.getElementById('nomor_hp_ortu');
|
||||
|
||||
if (nomorHpInput) {
|
||||
nomorHpInput.addEventListener('input', function(e) {
|
||||
// Hanya izinkan angka, +, -, spasi, dan tanda kurung
|
||||
let value = e.target.value.replace(/[^\d+\-\s()]/g, '');
|
||||
e.target.value = value;
|
||||
});
|
||||
|
||||
nomorHpInput.addEventListener('blur', function(e) {
|
||||
// Auto-format saat user selesai mengetik
|
||||
let value = e.target.value.trim();
|
||||
|
||||
// Jika dimulai dengan 0 dan panjangnya cukup
|
||||
if (value.startsWith('0') && value.length >= 10) {
|
||||
// Format: 0812-3456-7890
|
||||
value = value.replace(/\D/g, ''); // Hapus non-digit
|
||||
if (value.length >= 11) {
|
||||
value = value.substring(0, 4) + '-' +
|
||||
value.substring(4, 8) + '-' +
|
||||
value.substring(8, 12);
|
||||
}
|
||||
}
|
||||
// Jika dimulai dengan +62
|
||||
else if (value.startsWith('+62') && value.length >= 12) {
|
||||
value = value.replace(/[^\d+]/g, ''); // Hapus non-digit kecuali +
|
||||
if (value.length >= 13) {
|
||||
value = '+62' + value.substring(3, 6) + '-' +
|
||||
value.substring(6, 10) + '-' +
|
||||
value.substring(10, 14);
|
||||
}
|
||||
}
|
||||
|
||||
e.target.value = value;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/profil/edit.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -10,6 +10,35 @@
|
|||
</div>
|
||||
|
||||
|
||||
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 12px; margin-bottom: 20px;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; align-items: center;">
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📅 Periode Kuota</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">
|
||||
<?php echo e($settings->periode_mulai->format('d M Y')); ?> - <?php echo e($settings->periode_akhir->format('d M Y')); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">📊 Kuota Maksimal</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;"><?php echo e($settings->kuota_maksimal); ?> Hari / Tahun</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 style="margin: 0 0 5px 0; opacity: 0.9;">🔄 Terakhir Reset</h4>
|
||||
<p style="margin: 0; font-size: 1.1rem; font-weight: 600;">
|
||||
<?php echo e($settings->terakhir_reset ? $settings->terakhir_reset->format('d M Y') : 'Belum Pernah'); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<a href="<?php echo e(route('admin.kepulangan.settings')); ?>" class="btn btn-light" style="background: white; color: #667eea; font-weight: 600;">
|
||||
<i class="fas fa-cog"></i> Kelola Pengaturan
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
<h3>Total Data</h3>
|
||||
|
|
@ -27,9 +56,14 @@
|
|||
<i class="fas fa-home card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-danger">
|
||||
<h3>Over Limit</h3>
|
||||
<h3>Over Limit (><?php echo e($settings->kuota_maksimal); ?> Hari)</h3>
|
||||
<div class="card-value"><?php echo e($stats['over_limit_santri']); ?></div>
|
||||
<i class="fas fa-exclamation-triangle card-icon"></i>
|
||||
<?php if($stats['over_limit_santri'] > 0): ?>
|
||||
<a href="<?php echo e(route('admin.kepulangan.over-limit')); ?>" style="font-size: 0.85rem; color: #dc3545; text-decoration: underline; margin-top: 5px; display: block;">
|
||||
Lihat Detail
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -66,7 +100,7 @@
|
|||
<input type="text"
|
||||
name="search"
|
||||
class="form-control"
|
||||
placeholder="Nama, ID, atau alasan..."
|
||||
placeholder="Cari nama, ID, atau alasan..."
|
||||
value="<?php echo e(request('search')); ?>"
|
||||
id="searchInput">
|
||||
</div>
|
||||
|
|
@ -126,6 +160,7 @@ class="form-control"
|
|||
<th>Tanggal Pulang</th>
|
||||
<th>Tanggal Kembali</th>
|
||||
<th>Durasi</th>
|
||||
<th>Total Kuota Terpakai</th>
|
||||
<th>Alasan</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
|
|
@ -133,12 +168,16 @@ class="form-control"
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $kepulangan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr style="<?php echo e(isset($santriOverLimit[$item->id_santri]) ? 'background-color: #fff3cd;' : ''); ?>">
|
||||
<?php
|
||||
$isOverLimit = isset($santriOverLimit[$item->id_santri]);
|
||||
$totalHariTerpakai = $isOverLimit ? $santriOverLimit[$item->id_santri] : 0;
|
||||
?>
|
||||
<tr style="<?php echo e($isOverLimit ? 'background-color: rgba(220, 53, 69, 0.1); border-left: 4px solid #dc3545;' : ''); ?>">
|
||||
<td>
|
||||
<strong><?php echo e($item->id_kepulangan); ?></strong>
|
||||
<?php if(isset($santriOverLimit[$item->id_santri])): ?>
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.75rem; margin-left: 5px;"
|
||||
title="Over Limit: <?php echo e($santriOverLimit[$item->id_santri]); ?> hari">
|
||||
<?php if($isOverLimit): ?>
|
||||
<span style="display: inline-block; background: #dc3545; color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.75rem; margin-left: 5px; animation: pulse 2s infinite;"
|
||||
title="Over Limit: <?php echo e($totalHariTerpakai); ?> hari">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
|
|
@ -155,10 +194,31 @@ class="form-control"
|
|||
<td><?php echo e($item->tanggal_pulang_formatted); ?></td>
|
||||
<td><?php echo e($item->tanggal_kembali_formatted); ?></td>
|
||||
<td>
|
||||
<span style="display: inline-block; background: <?php echo e($item->durasi_izin_calculated > 7 ? '#ffc107' : '#6c757d'); ?>; color: <?php echo e($item->durasi_izin_calculated > 7 ? '#000' : '#fff'); ?>; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem;">
|
||||
<?php echo e($item->durasi_izin_calculated); ?> hari
|
||||
<span style="display: inline-block; background: <?php echo e($item->durasi_izin > 7 ? '#ffc107' : '#6c757d'); ?>; color: <?php echo e($item->durasi_izin > 7 ? '#000' : '#fff'); ?>; padding: 4px 8px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;">
|
||||
<?php echo e($item->durasi_izin); ?> hari
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$kuotaSantri = \App\Models\Kepulangan::getSisaKuotaSantri($item->id_santri);
|
||||
$badgeColor = $kuotaSantri['badge_color'];
|
||||
$badgeColors = [
|
||||
'success' => '#28a745',
|
||||
'warning' => '#ffc107',
|
||||
'danger' => '#dc3545'
|
||||
];
|
||||
$bgColor = $badgeColors[$badgeColor] ?? '#6c757d';
|
||||
$textColor = $badgeColor == 'warning' ? '#000' : '#fff';
|
||||
?>
|
||||
<div style="text-align: center;">
|
||||
<span style="display: inline-block; background: <?php echo e($bgColor); ?>; color: <?php echo e($textColor); ?>; padding: 4px 10px; border-radius: 4px; font-size: 0.85rem; font-weight: 600;">
|
||||
<?php echo e($kuotaSantri['total_terpakai']); ?> / <?php echo e($kuotaSantri['kuota_maksimal']); ?> hari
|
||||
</span>
|
||||
<div style="margin-top: 5px; font-size: 0.75rem; color: #7F8C8D;">
|
||||
Sisa: <?php echo e($kuotaSantri['sisa_kuota']); ?> hari (<?php echo e($kuotaSantri['persentase']); ?>%)
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span style="max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block;" title="<?php echo e($item->alasan); ?>">
|
||||
<?php echo e($item->alasan); ?>
|
||||
|
|
@ -176,9 +236,9 @@ class="form-control"
|
|||
|
||||
</span>
|
||||
<?php if($item->is_aktif): ?>
|
||||
<br><small style="color: #28a745; font-weight: 600;">Sedang Izin</small>
|
||||
<br><small style="color: #28a745; font-weight: 600;">🏠 Sedang Izin</small>
|
||||
<?php elseif($item->is_terlambat): ?>
|
||||
<br><small style="color: #dc3545; font-weight: 600;">Terlambat</small>
|
||||
<br><small style="color: #dc3545; font-weight: 600;">⏰ Terlambat</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
|
|
@ -234,7 +294,7 @@ class="btn btn-sm btn-danger"
|
|||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="8" style="text-align: center; padding: 40px;">
|
||||
<td colspan="9" style="text-align: center; padding: 40px;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; color: #ccc; margin-bottom: 15px;"></i>
|
||||
<p style="color: #7F8C8D;">Tidak ada data kepulangan ditemukan</p>
|
||||
</td>
|
||||
|
|
@ -284,7 +344,6 @@ class="btn btn-sm btn-danger"
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade" id="rejectModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -309,7 +368,6 @@ class="btn btn-sm btn-danger"
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" style="display: none;">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content" style="background: white; border-radius: 12px; padding: 20px;">
|
||||
|
|
@ -332,12 +390,17 @@ class="btn btn-sm btn-danger"
|
|||
.modal.fade { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }
|
||||
.modal-dialog { max-width: 500px; width: 90%; margin: auto; }
|
||||
.modal-content { max-height: 90vh; overflow-y: auto; }
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let currentActionId = null;
|
||||
|
||||
// Auto submit search with debounce
|
||||
// Auto submit search dengan debounce
|
||||
let searchTimeout;
|
||||
document.getElementById('searchInput')?.addEventListener('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-chart-bar"></i> Rekap Absensi: <?php echo e($kegiatan->nama_kegiatan); ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-success">
|
||||
<h3>Hadir</h3>
|
||||
<div class="card-value"><?php echo e($stats['Hadir'] ?? 0); ?></div>
|
||||
<i class="fas fa-check-circle card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-warning">
|
||||
<h3>Izin</h3>
|
||||
<div class="card-value"><?php echo e($stats['Izin'] ?? 0); ?></div>
|
||||
<i class="fas fa-info-circle card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-info">
|
||||
<h3>Sakit</h3>
|
||||
<div class="card-value"><?php echo e($stats['Sakit'] ?? 0); ?></div>
|
||||
<i class="fas fa-heartbeat card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-danger">
|
||||
<h3>Alpa</h3>
|
||||
<div class="card-value"><?php echo e($stats['Alpa'] ?? 0); ?></div>
|
||||
<i class="fas fa-times-circle card-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div style="margin-bottom: 20px;">
|
||||
<form method="GET" class="filter-form-inline">
|
||||
<input type="date" name="tanggal" class="form-control" value="<?php echo e(request('tanggal')); ?>">
|
||||
<input type="month" name="bulan" class="form-control" value="<?php echo e(request('bulan')); ?>" placeholder="Pilih Bulan">
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
|
||||
<?php if(request()->hasAny(['tanggal', 'bulan'])): ?>
|
||||
<a href="<?php echo e(route('admin.absensi-kegiatan.rekap', $kegiatan->kegiatan_id)); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i> Reset
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="<?php echo e(route('admin.absensi-kegiatan.index')); ?>" class="btn btn-secondary" style="margin-left: auto;">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if($absensis->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">No</th>
|
||||
<th style="width: 100px;">Tanggal</th>
|
||||
<th style="width: 100px;">ID Santri</th>
|
||||
<th>Nama Santri</th>
|
||||
<th style="width: 80px;">Kelas</th>
|
||||
<th style="width: 120px; text-align: center;">Status</th>
|
||||
<th style="width: 100px;">Metode</th>
|
||||
<th style="width: 100px;">Waktu</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $absensis; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $absensi): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($absensis->firstItem() + $index); ?></td>
|
||||
<td><?php echo e($absensi->tanggal->format('d/m/Y')); ?></td>
|
||||
<td><strong><?php echo e($absensi->id_santri); ?></strong></td>
|
||||
<td><?php echo e($absensi->santri->nama_lengkap); ?></td>
|
||||
<td><span class="badge badge-secondary"><?php echo e($absensi->santri->kelas); ?></span></td>
|
||||
<td class="text-center"><?php echo $absensi->status_badge; ?></td>
|
||||
<td>
|
||||
<?php if($absensi->metode_absen == 'RFID'): ?>
|
||||
<span class="badge badge-primary"><i class="fas fa-id-card"></i> RFID</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-secondary"><i class="fas fa-hand-pointer"></i> Manual</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo e($absensi->waktu_absen ? date('H:i', strtotime($absensi->waktu_absen)) : '-'); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($absensis->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-clipboard"></i>
|
||||
<h3>Belum Ada Data Absensi</h3>
|
||||
<p>Silakan input absensi terlebih dahulu.</p>
|
||||
<a href="<?php echo e(route('admin.absensi-kegiatan.input', $kegiatan->kegiatan_id)); ?>" class="btn btn-success">
|
||||
<i class="fas fa-clipboard-check"></i> Input Absensi
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/absensi/rekap.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-file-alt"></i> Detail Riwayat Absensi</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<h3>Riwayat Absensi #<?php echo e($riwayat->absensi_id); ?></h3>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.edit', $riwayat->id)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.riwayat-kegiatan.destroy', $riwayat->id)); ?>" method="POST" style="display: inline;" onsubmit="return confirm('Yakin ingin menghapus riwayat ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Hapus
|
||||
</button>
|
||||
</form>
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-user"></i> Informasi Santri</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Santri</th>
|
||||
<td><strong><?php echo e($riwayat->santri->id_santri); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nama Lengkap</th>
|
||||
<td><?php echo e($riwayat->santri->nama_lengkap); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kelas</th>
|
||||
<td><span class="badge badge-secondary badge-lg"><?php echo e($riwayat->santri->kelas); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status Santri</th>
|
||||
<td><span class="badge badge-success badge-lg"><?php echo e($riwayat->santri->status); ?></span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-calendar-alt"></i> Informasi Kegiatan</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Kegiatan</th>
|
||||
<td><strong><?php echo e($riwayat->kegiatan->kegiatan_id); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nama Kegiatan</th>
|
||||
<td><?php echo e($riwayat->kegiatan->nama_kegiatan); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kategori</th>
|
||||
<td><span class="badge badge-primary badge-lg"><?php echo e($riwayat->kegiatan->kategori->nama_kategori); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hari</th>
|
||||
<td><span class="badge badge-info badge-lg"><?php echo e($riwayat->kegiatan->hari); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Waktu Pelaksanaan</th>
|
||||
<td>
|
||||
<i class="fas fa-clock" style="color: var(--primary-color);"></i>
|
||||
<?php echo e(date('H:i', strtotime($riwayat->kegiatan->waktu_mulai))); ?> -
|
||||
<?php echo e(date('H:i', strtotime($riwayat->kegiatan->waktu_selesai))); ?> WIB
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-clipboard-check"></i> Detail Absensi</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Absensi</th>
|
||||
<td><strong><?php echo e($riwayat->absensi_id); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Tanggal Absensi</th>
|
||||
<td><?php echo e($riwayat->tanggal->format('d F Y')); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status Kehadiran</th>
|
||||
<td><?php echo $riwayat->status_badge; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Metode Absensi</th>
|
||||
<td>
|
||||
<?php if($riwayat->metode_absen == 'RFID'): ?>
|
||||
<span class="badge badge-primary badge-lg">
|
||||
<i class="fas fa-id-card"></i> RFID
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-secondary badge-lg">
|
||||
<i class="fas fa-hand-pointer"></i> Manual
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Waktu Absen</th>
|
||||
<td>
|
||||
<?php if($riwayat->waktu_absen): ?>
|
||||
<i class="fas fa-clock" style="color: var(--primary-color);"></i>
|
||||
<?php echo e(date('H:i:s', strtotime($riwayat->waktu_absen))); ?> WIB
|
||||
<?php else: ?>
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Dicatat Pada</th>
|
||||
<td><?php echo e($riwayat->created_at->format('d F Y, H:i:s')); ?> WIB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Terakhir Diubah</th>
|
||||
<td><?php echo e($riwayat->updated_at->format('d F Y, H:i:s')); ?> WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/riwayat/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Manajemen Akun Santri'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-user-cog"></i> Manajemen Akun Santri</h2>
|
||||
</div>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success"><?php echo e(session('success')); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="content-header-flex">
|
||||
<a href="<?php echo e(route('admin.users.santri_create')); ?>" class="btn btn-primary"><i class="fas fa-plus"></i> Buat Akun Santri</a>
|
||||
</div>
|
||||
|
||||
<h3>Daftar Akun Santri (<?php echo e($users->count()); ?>)</h3>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID Santri</th>
|
||||
<th>Nama</th>
|
||||
<th>Username</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $users; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $user): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td><?php echo e($user->role_id); ?></td>
|
||||
<td><?php echo e($user->name); ?></td>
|
||||
<td><?php echo e($user->username); ?></td>
|
||||
<td>
|
||||
<a href="#" class="btn btn-sm btn-warning"><i class="fas fa-key"></i> Reset Password</a>
|
||||
<a href="#" class="btn btn-sm btn-danger"><i class="fas fa-trash"></i> Hapus Akun</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center">Belum ada akun Santri yang terdaftar.</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3 style="margin-top: 30px;">Data Santri Tanpa Akun (<?php echo e($santris_tanpa_akun->count()); ?>)</h3>
|
||||
<p>Berikut adalah data santri yang sudah terdaftar di Data Santri namun belum memiliki akun login. Mereka dapat dipilih saat Anda membuat akun baru.</p>
|
||||
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', ['isAdmin' => true], \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/users/santri_accounts.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-history"></i> Riwayat Kegiatan & Absensi</h2>
|
||||
</div>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Statistik Cards -->
|
||||
<div class="row-cards">
|
||||
<div class="card card-success">
|
||||
<h3>Total Hadir</h3>
|
||||
<div class="card-value"><?php echo e($stats['Hadir'] ?? 0); ?></div>
|
||||
<i class="fas fa-check-circle card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-warning">
|
||||
<h3>Total Izin</h3>
|
||||
<div class="card-value"><?php echo e($stats['Izin'] ?? 0); ?></div>
|
||||
<i class="fas fa-info-circle card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-info">
|
||||
<h3>Total Sakit</h3>
|
||||
<div class="card-value"><?php echo e($stats['Sakit'] ?? 0); ?></div>
|
||||
<i class="fas fa-heartbeat card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-danger">
|
||||
<h3>Total Alpa</h3>
|
||||
<div class="card-value"><?php echo e($stats['Alpa'] ?? 0); ?></div>
|
||||
<i class="fas fa-times-circle card-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grafik Kehadiran -->
|
||||
<?php if(($stats['Hadir'] ?? 0) + ($stats['Izin'] ?? 0) + ($stats['Sakit'] ?? 0) + ($stats['Alpa'] ?? 0) > 0): ?>
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<h3 style="margin: 0 0 20px 0; color: var(--primary-color);">
|
||||
<i class="fas fa-chart-pie"></i> Grafik Statistik Kehadiran
|
||||
</h3>
|
||||
<canvas id="chartKehadiran" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Filter -->
|
||||
<div class="content-box">
|
||||
<form method="GET" style="margin-bottom: 20px;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="id_santri" style="font-size: 0.85rem; margin-bottom: 5px;">Santri</label>
|
||||
<select name="id_santri" id="id_santri" class="form-control">
|
||||
<option value="">-- Semua Santri --</option>
|
||||
<?php $__currentLoopData = $santris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $s): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($s->id_santri); ?>" <?php echo e(request('id_santri') == $s->id_santri ? 'selected' : ''); ?>>
|
||||
<?php echo e($s->nama_lengkap); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="kategori_id" style="font-size: 0.85rem; margin-bottom: 5px;">Kategori</label>
|
||||
<select name="kategori_id" id="kategori_id" class="form-control">
|
||||
<option value="">-- Semua Kategori --</option>
|
||||
<?php $__currentLoopData = $kategoris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $k): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($k->kategori_id); ?>" <?php echo e(request('kategori_id') == $k->kategori_id ? 'selected' : ''); ?>>
|
||||
<?php echo e($k->nama_kategori); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="kegiatan_id" style="font-size: 0.85rem; margin-bottom: 5px;">Kegiatan</label>
|
||||
<select name="kegiatan_id" id="kegiatan_id" class="form-control">
|
||||
<option value="">-- Semua Kegiatan --</option>
|
||||
<?php $__currentLoopData = $kegiatans; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $kg): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($kg->kegiatan_id); ?>" <?php echo e(request('kegiatan_id') == $kg->kegiatan_id ? 'selected' : ''); ?>>
|
||||
<?php echo e($kg->nama_kegiatan); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="status" style="font-size: 0.85rem; margin-bottom: 5px;">Status</label>
|
||||
<select name="status" id="status" class="form-control">
|
||||
<option value="">-- Semua Status --</option>
|
||||
<option value="Hadir" <?php echo e(request('status') == 'Hadir' ? 'selected' : ''); ?>>Hadir</option>
|
||||
<option value="Izin" <?php echo e(request('status') == 'Izin' ? 'selected' : ''); ?>>Izin</option>
|
||||
<option value="Sakit" <?php echo e(request('status') == 'Sakit' ? 'selected' : ''); ?>>Sakit</option>
|
||||
<option value="Alpa" <?php echo e(request('status') == 'Alpa' ? 'selected' : ''); ?>>Alpa</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="tanggal_dari" style="font-size: 0.85rem; margin-bottom: 5px;">Tanggal Dari</label>
|
||||
<input type="date" name="tanggal_dari" id="tanggal_dari" class="form-control" value="<?php echo e(request('tanggal_dari')); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="tanggal_sampai" style="font-size: 0.85rem; margin-bottom: 5px;">Tanggal Sampai</label>
|
||||
<input type="date" name="tanggal_sampai" id="tanggal_sampai" class="form-control" value="<?php echo e(request('tanggal_sampai')); ?>">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="margin: 0;">
|
||||
<label for="bulan" style="font-size: 0.85rem; margin-bottom: 5px;">Atau Pilih Bulan</label>
|
||||
<input type="month" name="bulan" id="bulan" class="form-control" value="<?php echo e(request('bulan')); ?>">
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: flex-end; gap: 10px;">
|
||||
<button type="submit" class="btn btn-primary" style="flex: 1;">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
<?php if(request()->hasAny(['id_santri', 'kategori_id', 'kegiatan_id', 'status', 'tanggal_dari', 'tanggal_sampai', 'bulan'])): ?>
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if($riwayats->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">No</th>
|
||||
<th style="width: 100px;">Tanggal</th>
|
||||
<th style="width: 100px;">ID Santri</th>
|
||||
<th>Nama Santri</th>
|
||||
<th>Kegiatan</th>
|
||||
<th style="width: 130px;">Kategori</th>
|
||||
<th style="width: 120px; text-align: center;">Status</th>
|
||||
<th style="width: 90px;">Metode</th>
|
||||
<th style="width: 180px; text-align: center;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $riwayats; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $riwayat): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($riwayats->firstItem() + $index); ?></td>
|
||||
<td><?php echo e($riwayat->tanggal->format('d/m/Y')); ?></td>
|
||||
<td><strong><?php echo e($riwayat->id_santri); ?></strong></td>
|
||||
<td>
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.detail-santri', $riwayat->id_santri)); ?>"
|
||||
style="color: var(--primary-color); text-decoration: none; font-weight: 500;">
|
||||
<?php echo e($riwayat->santri->nama_lengkap); ?>
|
||||
|
||||
</a>
|
||||
</td>
|
||||
<td><?php echo e($riwayat->kegiatan->nama_kegiatan); ?></td>
|
||||
<td><?php echo e($riwayat->kegiatan->kategori->nama_kategori); ?></td>
|
||||
<td class="text-center"><?php echo $riwayat->status_badge; ?></td>
|
||||
<td>
|
||||
<?php if($riwayat->metode_absen == 'RFID'): ?>
|
||||
<span class="badge badge-primary" style="font-size: 0.75rem;"><i class="fas fa-id-card"></i> RFID</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-secondary" style="font-size: 0.75rem;"><i class="fas fa-hand-pointer"></i> Manual</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.show', $riwayat->id)); ?>" class="btn btn-sm btn-primary" title="Detail">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.riwayat-kegiatan.edit', $riwayat->id)); ?>" class="btn btn-sm btn-warning" title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.riwayat-kegiatan.destroy', $riwayat->id)); ?>" method="POST" style="display: inline-block;" onsubmit="return confirm('Yakin ingin menghapus riwayat ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="Hapus">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($riwayats->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox"></i>
|
||||
<h3>Tidak Ada Riwayat</h3>
|
||||
<p>Belum ada data riwayat kegiatan dan absensi.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if(($stats['Hadir'] ?? 0) + ($stats['Izin'] ?? 0) + ($stats['Sakit'] ?? 0) + ($stats['Alpa'] ?? 0) > 0): ?>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
const ctx = document.getElementById('chartKehadiran');
|
||||
new Chart(ctx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Hadir', 'Izin', 'Sakit', 'Alpa'],
|
||||
datasets: [{
|
||||
data: [
|
||||
<?php echo e($stats['Hadir'] ?? 0); ?>,
|
||||
<?php echo e($stats['Izin'] ?? 0); ?>,
|
||||
<?php echo e($stats['Sakit'] ?? 0); ?>,
|
||||
<?php echo e($stats['Alpa'] ?? 0); ?>
|
||||
|
||||
],
|
||||
backgroundColor: [
|
||||
'#6FBA9D',
|
||||
'#FFD56B',
|
||||
'#81C6E8',
|
||||
'#FF8B94'
|
||||
],
|
||||
borderWidth: 2,
|
||||
borderColor: '#fff'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 15,
|
||||
font: { size: 13 }
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
let total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||
let value = context.parsed;
|
||||
let percentage = ((value / total) * 100).toFixed(1);
|
||||
return context.label + ': ' + value + ' (' + percentage + '%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/riwayat/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Riwayat Kegiatan & Absensi'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-calendar-check"></i> Riwayat Kegiatan & Absensi</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
<?php echo e($santri->nama_lengkap); ?> - Kelas <?php echo e($santri->kelas); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 25px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
||||
<h3 style="margin: 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-clock"></i> Jadwal Kegiatan Hari Ini (<?php echo e(ucfirst($hariIni)); ?>)
|
||||
</h3>
|
||||
<span class="badge badge-primary badge-lg">
|
||||
<i class="fas fa-calendar-day"></i> <?php echo e(\Carbon\Carbon::now()->locale('id')->isoFormat('D MMMM YYYY')); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<?php if($jadwalHariIni->count() > 0): ?>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px;">
|
||||
<?php $__currentLoopData = $jadwalHariIni; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $jadwal): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div style="background: white; padding: 18px; border-radius: var(--border-radius-sm); border-left: 4px solid <?php echo e(isset($absensiHariIni[$jadwal->kegiatan_id]) ? 'var(--success-color)' : 'var(--warning-color)'); ?>; display: flex; justify-content: space-between; align-items: center; box-shadow: var(--shadow-sm);">
|
||||
<div style="flex: 1;">
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
|
||||
<span class="badge badge-info"><?php echo e($jadwal->kategori->nama_kategori); ?></span>
|
||||
<h4 style="margin: 0; font-size: 1.1rem; color: var(--text-color);"><?php echo e($jadwal->nama_kegiatan); ?></h4>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 15px; font-size: 0.9rem; color: var(--text-light);">
|
||||
<span><i class="fas fa-clock"></i> <?php echo e(date('H:i', strtotime($jadwal->waktu_mulai))); ?> - <?php echo e(date('H:i', strtotime($jadwal->waktu_selesai))); ?></span>
|
||||
<?php if($jadwal->materi): ?>
|
||||
<span><i class="fas fa-book"></i> <?php echo e($jadwal->materi); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<?php if(isset($absensiHariIni[$jadwal->kegiatan_id])): ?>
|
||||
<span class="badge badge-success badge-lg">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e($absensiHariIni[$jadwal->kegiatan_id]); ?>
|
||||
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-warning badge-lg">
|
||||
<i class="fas fa-hourglass-half"></i> Belum Absen
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state" style="padding: 40px; text-align: center;">
|
||||
<i class="fas fa-calendar-times" style="font-size: 3rem; color: #ccc;"></i>
|
||||
<p style="margin-top: 15px; color: var(--text-light);">Tidak ada jadwal kegiatan untuk hari ini.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards" style="margin-bottom: 25px;">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-check-circle"></i> Total Kehadiran</h3>
|
||||
<div class="card-value"><?php echo e($stats30Hari['Hadir'] ?? 0); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-check-circle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">30 hari terakhir</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-percentage"></i> Persentase Kehadiran</h3>
|
||||
<div class="card-value"><?php echo e($persentaseKehadiran); ?>%</div>
|
||||
<div class="card-icon"><i class="fas fa-chart-line"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?php echo e($persentaseKehadiran); ?>%; background: var(--info-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> Izin / Sakit / Alpa</h3>
|
||||
<div class="card-value"><?php echo e(($stats30Hari['Izin'] ?? 0) + ($stats30Hari['Sakit'] ?? 0) + ($stats30Hari['Alpa'] ?? 0)); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-exclamation-triangle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Izin: <?php echo e($stats30Hari['Izin'] ?? 0); ?> | Sakit: <?php echo e($stats30Hari['Sakit'] ?? 0); ?> | Alpa: <?php echo e($stats30Hari['Alpa'] ?? 0); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<h3><i class="fas fa-list-check"></i> Total Kegiatan</h3>
|
||||
<div class="card-value"><?php echo e($totalKegiatan30Hari); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-list-check"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">30 hari terakhir</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); gap: 25px; margin-bottom: 25px;">
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-line"></i> Tren Kehadiran (4 Minggu Terakhir)
|
||||
</h3>
|
||||
<canvas id="chartTrenKehadiran" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-bar"></i> Kehadiran per Kategori Kegiatan
|
||||
</h3>
|
||||
<canvas id="chartKategori" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px;">
|
||||
<h3 style="margin: 0; color: var(--text-color);">
|
||||
<i class="fas fa-history"></i> Riwayat Absensi Lengkap
|
||||
</h3>
|
||||
|
||||
|
||||
<form method="GET" action="<?php echo e(route('santri.kegiatan.index')); ?>" style="display: flex; gap: 10px; flex-wrap: wrap;">
|
||||
<input type="month" name="bulan" class="form-control" value="<?php echo e(request('bulan')); ?>"
|
||||
style="max-width: 200px;" placeholder="Pilih Bulan">
|
||||
<select name="status" class="form-control" style="max-width: 150px;">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="Hadir" <?php echo e(request('status') == 'Hadir' ? 'selected' : ''); ?>>Hadir</option>
|
||||
<option value="Izin" <?php echo e(request('status') == 'Izin' ? 'selected' : ''); ?>>Izin</option>
|
||||
<option value="Sakit" <?php echo e(request('status') == 'Sakit' ? 'selected' : ''); ?>>Sakit</option>
|
||||
<option value="Alpa" <?php echo e(request('status') == 'Alpa' ? 'selected' : ''); ?>>Alpa</option>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
<a href="<?php echo e(route('santri.kegiatan.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php if($riwayats->count() > 0): ?>
|
||||
<div class="table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Tanggal</th>
|
||||
<th>Kegiatan</th>
|
||||
<th>Kategori</th>
|
||||
<th>Waktu Absen</th>
|
||||
<th>Status</th>
|
||||
<th>Metode</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $riwayats; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $absensi): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($riwayats->firstItem() + $index); ?></td>
|
||||
<td><?php echo e($absensi->tanggal_formatted); ?></td>
|
||||
<td><strong><?php echo e($absensi->kegiatan->nama_kegiatan); ?></strong></td>
|
||||
<td><span class="badge badge-info"><?php echo e($absensi->kegiatan->kategori->nama_kategori); ?></span></td>
|
||||
<td><?php echo e($absensi->waktu_absen_formatted); ?></td>
|
||||
<td>
|
||||
<span class="badge <?php echo e($absensi->status_badge_class); ?>">
|
||||
<i class="fas fa-<?php echo e($absensi->status == 'Hadir' ? 'check' : ($absensi->status == 'Izin' ? 'info-circle' : ($absensi->status == 'Sakit' ? 'heartbeat' : 'times'))); ?>-circle"></i>
|
||||
<?php echo e($absensi->status); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td><span class="badge badge-secondary"><?php echo e($absensi->metode_absen); ?></span></td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('santri.kegiatan.show', $absensi->kegiatan_id)); ?>" class="btn btn-sm btn-primary" title="Lihat Detail Kegiatan">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($riwayats->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-inbox"></i>
|
||||
<h3>Belum Ada Riwayat Absensi</h3>
|
||||
<p>Riwayat absensi Anda akan muncul di sini setelah mengikuti kegiatan.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 1: Tren Kehadiran per Minggu (LINE CHART)
|
||||
// ============================================
|
||||
const ctxTren = document.getElementById('chartTrenKehadiran');
|
||||
if (ctxTren) {
|
||||
new Chart(ctxTren.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [
|
||||
<?php $__currentLoopData = $dataGrafikMingguan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $data): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
'<?php echo e($data["minggu"]); ?>',
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Hadir',
|
||||
data: [
|
||||
<?php $__currentLoopData = $dataGrafikMingguan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $data): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($data['hadir']); ?>,
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
borderColor: 'rgba(111, 186, 157, 1)',
|
||||
backgroundColor: 'rgba(111, 186, 157, 0.2)',
|
||||
borderWidth: 3,
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: 'rgba(111, 186, 157, 1)',
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
},
|
||||
{
|
||||
label: 'Total Kegiatan',
|
||||
data: [
|
||||
<?php $__currentLoopData = $dataGrafikMingguan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $data): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($data['total']); ?>,
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
borderColor: 'rgba(129, 198, 232, 1)',
|
||||
backgroundColor: 'rgba(129, 198, 232, 0.1)',
|
||||
borderWidth: 2,
|
||||
pointRadius: 4,
|
||||
pointBackgroundColor: 'rgba(129, 198, 232, 1)',
|
||||
tension: 0.4,
|
||||
fill: true,
|
||||
borderDash: [5, 5]
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
labels: {
|
||||
font: { size: 12, weight: '600' },
|
||||
padding: 15
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return context.dataset.label + ': ' + context.parsed.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1,
|
||||
font: { size: 12, weight: '600' }
|
||||
},
|
||||
grid: { color: 'rgba(0, 0, 0, 0.05)' }
|
||||
},
|
||||
x: {
|
||||
ticks: { font: { size: 12, weight: '600' } },
|
||||
grid: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 2: Kehadiran per Kategori (BAR CHART)
|
||||
// ============================================
|
||||
const ctxKategori = document.getElementById('chartKategori');
|
||||
if (ctxKategori) {
|
||||
new Chart(ctxKategori.getContext('2d'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
<?php $__currentLoopData = $statsByKategori; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $stat): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
'<?php echo e($stat->nama_kategori); ?>',
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
datasets: [{
|
||||
label: 'Kehadiran',
|
||||
data: [
|
||||
<?php $__currentLoopData = $statsByKategori; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $stat): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($stat->hadir); ?>,
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
'rgba(255, 139, 148, 0.8)',
|
||||
'rgba(179, 157, 219, 0.8)',
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(111, 186, 157, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(255, 213, 107, 1)',
|
||||
'rgba(255, 139, 148, 1)',
|
||||
'rgba(179, 157, 219, 1)',
|
||||
],
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
borderSkipped: false
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: { display: false },
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Hadir: ' + context.parsed.y + ' kali';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1,
|
||||
font: { size: 12, weight: '600' }
|
||||
},
|
||||
grid: { color: 'rgba(0, 0, 0, 0.05)' }
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: { size: 11 },
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
},
|
||||
grid: { display: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/kegiatan/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-calendar-alt"></i> Manajemen Semester</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(session('error')): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php echo e(session('error')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="content-header-flex">
|
||||
<a href="<?php echo e(route('admin.semester.create')); ?>" class="btn btn-success">
|
||||
<i class="fas fa-plus"></i> Tambah Semester
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<?php if($semesters->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">No</th>
|
||||
<th style="width: 10%;">ID Semester</th>
|
||||
<th style="width: 25%;">Nama Semester</th>
|
||||
<th style="width: 15%;">Tahun Ajaran</th>
|
||||
<th style="width: 10%;">Periode</th>
|
||||
<th style="width: 15%;">Tanggal</th>
|
||||
<th style="width: 10%;">Status</th>
|
||||
<th class="text-center" style="width: 10%;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $semesters; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $semester): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($semesters->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($semester->id_semester); ?></strong></td>
|
||||
<td><?php echo e($semester->nama_semester); ?></td>
|
||||
<td><?php echo e($semester->tahun_ajaran); ?></td>
|
||||
<td class="text-center">
|
||||
<span class="badge <?php echo e($semester->periode == 1 ? 'badge-info' : 'badge-warning'); ?>">
|
||||
Semester <?php echo e($semester->periode); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<small>
|
||||
<?php echo e($semester->tanggal_mulai->format('d/m/Y')); ?> -<br>
|
||||
<?php echo e($semester->tanggal_akhir->format('d/m/Y')); ?>
|
||||
|
||||
</small>
|
||||
</td>
|
||||
<td><?php echo $semester->status_badge; ?></td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group">
|
||||
<a href="<?php echo e(route('admin.semester.show', $semester)); ?>"
|
||||
class="btn btn-sm btn-info" title="Detail">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.semester.edit', $semester)); ?>"
|
||||
class="btn btn-sm btn-warning" title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.semester.destroy', $semester)); ?>"
|
||||
method="POST" style="display: inline-block;"
|
||||
onsubmit="return confirm('Yakin ingin menghapus semester ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="Hapus">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($semesters->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-calendar-times"></i>
|
||||
<h3>Belum Ada Semester</h3>
|
||||
<p>Silakan tambahkan semester terlebih dahulu sebelum mengelola capaian santri.</p>
|
||||
<a href="<?php echo e(route('admin.semester.create')); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> Tambah Semester Pertama
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/semester/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -18,9 +18,9 @@
|
|||
|
||||
|
||||
<li>
|
||||
<a href="#" class="<?php echo e(Request::routeIs('santri.absensi.*') ? 'active' : ''); ?>">
|
||||
<a href="<?php echo e(route('santri.kegiatan.index')); ?>" class="<?php echo e(Request::routeIs('santri.kegiatan.*') ? 'active' : ''); ?>">
|
||||
<i class="fas fa-calendar-check"></i>
|
||||
<span>Riwayat Absensi</span>
|
||||
<span>Kegiatan & Absensi</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Foto</th>
|
||||
<th>ID Santri</th>
|
||||
<th>NIS</th>
|
||||
<th>Nama Lengkap</th>
|
||||
|
|
@ -68,7 +69,21 @@
|
|||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $santris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td><?php echo e($index + 1); ?></td>
|
||||
<td><?php echo e($santris->firstItem() + $index); ?></td>
|
||||
<td>
|
||||
|
||||
<?php if($santri->foto): ?>
|
||||
<img src="<?php echo e(asset('storage/' . $santri->foto)); ?>"
|
||||
alt="Foto <?php echo e($santri->nama_lengkap); ?>"
|
||||
style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover; border: 2px solid var(--primary-color);"
|
||||
loading="lazy">
|
||||
<?php else: ?>
|
||||
<div class="santri-avatar-initial" style="width: 40px; height: 40px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 0.9rem;">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><strong><?php echo e($santri->id_santri); ?></strong></td>
|
||||
<td><?php echo e($santri->nis ?? '-'); ?></td>
|
||||
<td><?php echo e($santri->nama_lengkap); ?></td>
|
||||
|
|
@ -108,7 +123,7 @@
|
|||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center" style="padding: 40px;">
|
||||
<td colspan="9" class="text-center" style="padding: 40px;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; color: #ccc; margin-bottom: 15px; display: block;"></i>
|
||||
<?php if(request('search') || request('status') || request('kelas')): ?>
|
||||
<strong>Data tidak ditemukan.</strong><br>
|
||||
|
|
@ -127,15 +142,15 @@
|
|||
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #E8F7F2;">
|
||||
<p style="color: #7F8C8D; font-size: 0.9rem;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Menampilkan <strong><?php echo e($santris->count()); ?></strong> data santri
|
||||
Menampilkan <strong><?php echo e($santris->count()); ?></strong> dari <strong><?php echo e($santris->total()); ?></strong> data santri
|
||||
<?php if(request('search') || request('status') || request('kelas')): ?>
|
||||
dari hasil pencarian/filter
|
||||
(hasil pencarian/filter)
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Pagination (jika menggunakan paginate) -->
|
||||
<!-- Pagination -->
|
||||
<?php if(method_exists($santris, 'links')): ?>
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($santris->links()); ?>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,282 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-clipboard-check"></i> Input Absensi: <?php echo e($kegiatan->nama_kegiatan); ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px;">
|
||||
<div>
|
||||
<h3 style="margin: 0; color: var(--primary-color);"><?php echo e($kegiatan->nama_kegiatan); ?></h3>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
<i class="fas fa-calendar-day"></i> <?php echo e($kegiatan->hari); ?> |
|
||||
<i class="fas fa-clock"></i> <?php echo e(date('H:i', strtotime($kegiatan->waktu_mulai))); ?> - <?php echo e(date('H:i', strtotime($kegiatan->waktu_selesai))); ?> |
|
||||
<i class="fas fa-list-alt"></i> <?php echo e($kegiatan->kategori->nama_kategori); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<button type="button" id="btnModeManual" class="btn btn-primary" onclick="setMode('manual')">
|
||||
<i class="fas fa-hand-pointer"></i> Mode Manual
|
||||
</button>
|
||||
<button type="button" id="btnModeRfid" class="btn btn-success" onclick="setMode('rfid')">
|
||||
<i class="fas fa-id-card"></i> Mode RFID
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MODE MANUAL -->
|
||||
<div id="modeManual" class="content-box">
|
||||
<form action="<?php echo e(route('admin.absensi-kegiatan.simpan')); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
<input type="hidden" name="kegiatan_id" value="<?php echo e($kegiatan->kegiatan_id); ?>">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="tanggal">
|
||||
<i class="fas fa-calendar form-icon"></i>
|
||||
Tanggal Absensi
|
||||
</label>
|
||||
<input type="date" name="tanggal" id="tanggal" class="form-control" value="<?php echo e($tanggal); ?>" required>
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
<p><i class="fas fa-info-circle"></i> Pilih status absensi untuk setiap santri. Jika tidak dipilih, akan dianggap <strong>Alpa</strong>.</p>
|
||||
</div>
|
||||
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50px;">No</th>
|
||||
<th style="width: 100px;">ID Santri</th>
|
||||
<th>Nama Santri</th>
|
||||
<th style="width: 100px;">Kelas</th>
|
||||
<th style="width: 300px; text-align: center;">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $santris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($index + 1); ?></td>
|
||||
<td><strong><?php echo e($santri->id_santri); ?></strong></td>
|
||||
<td><?php echo e($santri->nama_lengkap); ?></td>
|
||||
<td><span class="badge badge-secondary"><?php echo e($santri->kelas); ?></span></td>
|
||||
<td class="text-center">
|
||||
<?php
|
||||
$currentStatus = $absensiData[$santri->id_santri] ?? 'Alpa';
|
||||
?>
|
||||
<div style="display: flex; gap: 8px; justify-content: center;">
|
||||
<label style="margin: 0; cursor: pointer;">
|
||||
<input type="radio" name="absensi[<?php echo e($santri->id_santri); ?>]" value="Hadir"
|
||||
<?php echo e($currentStatus == 'Hadir' ? 'checked' : ''); ?> required>
|
||||
<span class="badge badge-success">Hadir</span>
|
||||
</label>
|
||||
<label style="margin: 0; cursor: pointer;">
|
||||
<input type="radio" name="absensi[<?php echo e($santri->id_santri); ?>]" value="Izin"
|
||||
<?php echo e($currentStatus == 'Izin' ? 'checked' : ''); ?>>
|
||||
<span class="badge badge-warning">Izin</span>
|
||||
</label>
|
||||
<label style="margin: 0; cursor: pointer;">
|
||||
<input type="radio" name="absensi[<?php echo e($santri->id_santri); ?>]" value="Sakit"
|
||||
<?php echo e($currentStatus == 'Sakit' ? 'checked' : ''); ?>>
|
||||
<span class="badge badge-info">Sakit</span>
|
||||
</label>
|
||||
<label style="margin: 0; cursor: pointer;">
|
||||
<input type="radio" name="absensi[<?php echo e($santri->id_santri); ?>]" value="Alpa"
|
||||
<?php echo e($currentStatus == 'Alpa' ? 'checked' : ''); ?>>
|
||||
<span class="badge badge-danger">Alpa</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="btn-group" style="margin-top: 20px;">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fas fa-save"></i> Simpan Absensi
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.absensi-kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- MODE RFID -->
|
||||
<div id="modeRfid" class="content-box" style="display: none;">
|
||||
<div class="form-group">
|
||||
<label for="tanggalRfid">
|
||||
<i class="fas fa-calendar form-icon"></i>
|
||||
Tanggal Absensi
|
||||
</label>
|
||||
<input type="date" id="tanggalRfid" class="form-control" value="<?php echo e($tanggal); ?>">
|
||||
</div>
|
||||
|
||||
<div class="info-box">
|
||||
<p><i class="fas fa-id-card"></i> Tempelkan kartu RFID santri ke reader. Absensi akan otomatis tersimpan sebagai <strong>Hadir</strong>.</p>
|
||||
</div>
|
||||
|
||||
<div style="background: linear-gradient(135deg, var(--primary-light) 0%, #D4F1E3 100%); padding: 30px; border-radius: var(--border-radius); text-align: center; margin-bottom: 20px;">
|
||||
<div id="rfidStatus" style="font-size: 1.5rem; font-weight: 600; color: var(--primary-color); margin-bottom: 15px;">
|
||||
<i class="fas fa-wifi"></i> Siap Scan RFID
|
||||
</div>
|
||||
<input type="text" id="rfidInput" placeholder="Fokus di sini untuk scan RFID..."
|
||||
style="width: 100%; padding: 15px; font-size: 1.2rem; border: 3px solid var(--primary-color); border-radius: var(--border-radius-sm); text-align: center;"
|
||||
autofocus>
|
||||
</div>
|
||||
|
||||
<div id="rfidLog" style="max-height: 400px; overflow-y: auto; background: white; border-radius: var(--border-radius-sm); padding: 15px; border: 1px solid var(--primary-light);">
|
||||
<h4 style="margin: 0 0 15px 0; color: var(--primary-color);"><i class="fas fa-history"></i> Log Absensi</h4>
|
||||
<div id="rfidLogContent">
|
||||
<p style="text-align: center; color: var(--text-light);">Belum ada absensi...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" style="margin-top: 20px;">
|
||||
<button type="button" class="btn btn-warning" onclick="clearLog()">
|
||||
<i class="fas fa-trash"></i> Bersihkan Log
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.absensi-kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let currentMode = 'manual';
|
||||
const kegiatanId = '<?php echo e($kegiatan->kegiatan_id); ?>';
|
||||
|
||||
function setMode(mode) {
|
||||
currentMode = mode;
|
||||
|
||||
if (mode === 'manual') {
|
||||
document.getElementById('modeManual').style.display = 'block';
|
||||
document.getElementById('modeRfid').style.display = 'none';
|
||||
document.getElementById('btnModeManual').classList.add('btn-primary');
|
||||
document.getElementById('btnModeManual').classList.remove('btn-secondary');
|
||||
document.getElementById('btnModeRfid').classList.remove('btn-success');
|
||||
document.getElementById('btnModeRfid').classList.add('btn-secondary');
|
||||
} else {
|
||||
document.getElementById('modeManual').style.display = 'none';
|
||||
document.getElementById('modeRfid').style.display = 'block';
|
||||
document.getElementById('btnModeManual').classList.remove('btn-primary');
|
||||
document.getElementById('btnModeManual').classList.add('btn-secondary');
|
||||
document.getElementById('btnModeRfid').classList.add('btn-success');
|
||||
document.getElementById('btnModeRfid').classList.remove('btn-secondary');
|
||||
document.getElementById('rfidInput').focus();
|
||||
}
|
||||
}
|
||||
|
||||
// RFID Scanner Handler
|
||||
document.getElementById('rfidInput').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const rfidUid = this.value.trim();
|
||||
|
||||
if (rfidUid) {
|
||||
scanRfid(rfidUid);
|
||||
this.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function scanRfid(rfidUid) {
|
||||
const tanggal = document.getElementById('tanggalRfid').value;
|
||||
const statusEl = document.getElementById('rfidStatus');
|
||||
|
||||
statusEl.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Memproses...';
|
||||
statusEl.style.color = 'var(--warning-color)';
|
||||
|
||||
fetch('<?php echo e(route("admin.absensi-kegiatan.scan-rfid")); ?>', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '<?php echo e(csrf_token()); ?>'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
rfid_uid: rfidUid,
|
||||
kegiatan_id: kegiatanId,
|
||||
tanggal: tanggal
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
statusEl.innerHTML = '<i class="fas fa-check-circle"></i> ' + data.message;
|
||||
statusEl.style.color = 'var(--success-color)';
|
||||
addLogEntry(data.data, 'success');
|
||||
playSound('success');
|
||||
} else {
|
||||
statusEl.innerHTML = '<i class="fas fa-exclamation-circle"></i> ' + data.message;
|
||||
statusEl.style.color = 'var(--danger-color)';
|
||||
playSound('error');
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
statusEl.innerHTML = '<i class="fas fa-wifi"></i> Siap Scan RFID';
|
||||
statusEl.style.color = 'var(--primary-color)';
|
||||
}, 2000);
|
||||
})
|
||||
.catch(error => {
|
||||
statusEl.innerHTML = '<i class="fas fa-times-circle"></i> Koneksi error';
|
||||
statusEl.style.color = 'var(--danger-color)';
|
||||
console.error('Error:', error);
|
||||
|
||||
setTimeout(() => {
|
||||
statusEl.innerHTML = '<i class="fas fa-wifi"></i> Siap Scan RFID';
|
||||
statusEl.style.color = 'var(--primary-color)';
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
function addLogEntry(data, type) {
|
||||
const logContent = document.getElementById('rfidLogContent');
|
||||
|
||||
if (logContent.querySelector('p')) {
|
||||
logContent.innerHTML = '';
|
||||
}
|
||||
|
||||
const entry = document.createElement('div');
|
||||
entry.style.cssText = 'padding: 12px; margin-bottom: 10px; border-radius: 8px; background: ' +
|
||||
(type === 'success' ? 'linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%)' : 'linear-gradient(135deg, #FFE8EA 0%, #FFD5D8 100%)') +
|
||||
'; border-left: 4px solid ' + (type === 'success' ? 'var(--success-color)' : 'var(--danger-color)');
|
||||
|
||||
entry.innerHTML = `
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div>
|
||||
<strong>${data.nama}</strong> (${data.id_santri})
|
||||
<div style="font-size: 0.85rem; color: var(--text-light); margin-top: 3px;">
|
||||
Kelas: ${data.kelas} | Waktu: ${data.waktu}
|
||||
</div>
|
||||
</div>
|
||||
<span class="badge badge-success"><i class="fas fa-check"></i> Hadir</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
logContent.insertBefore(entry, logContent.firstChild);
|
||||
}
|
||||
|
||||
function clearLog() {
|
||||
if (confirm('Yakin ingin membersihkan log?')) {
|
||||
document.getElementById('rfidLogContent').innerHTML = '<p style="text-align: center; color: var(--text-light);">Belum ada absensi...</p>';
|
||||
}
|
||||
}
|
||||
|
||||
function playSound(type) {
|
||||
// Bisa ditambahkan audio feedback
|
||||
const audio = new Audio(type === 'success' ? '/sounds/success.mp3' : '/sounds/error.mp3');
|
||||
audio.play().catch(() => {}); // Ignore errors
|
||||
}
|
||||
|
||||
// Auto-focus kembali ke input RFID jika kehilangan fokus
|
||||
setInterval(() => {
|
||||
if (currentMode === 'rfid' && document.activeElement !== document.getElementById('rfidInput')) {
|
||||
document.getElementById('rfidInput').focus();
|
||||
}
|
||||
}, 1000);
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/absensi/input.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Register Admin'); ?>
|
||||
|
||||
<?php $__env->startSection('auth-content'); ?>
|
||||
<div class="auth-header">
|
||||
<div class="logo-circle">
|
||||
<i class="fas fa-lock-open fa-2x"></i>
|
||||
</div>
|
||||
<h2>Pendaftaran Akun Admin</h2>
|
||||
<p>Mohon gunakan email dan password yang kuat untuk keamanan sistem.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="alert alert-danger">
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<p><?php echo e($error); ?></p>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="<?php echo e(route('admin.register')); ?>" class="data-form">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email"><i class="fas fa-envelope form-icon"></i> Email Admin</label>
|
||||
<input type="email" id="email" name="email" value="<?php echo e(old('email')); ?>" class="form-control <?php $__errorArgs = ['email'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required autofocus>
|
||||
<?php $__errorArgs = ['email'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="invalid-feedback"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password"><i class="fas fa-key form-icon"></i> Password</label>
|
||||
<input type="password" id="password" name="password" class="form-control <?php $__errorArgs = ['password'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<?php $__errorArgs = ['password'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?><div class="invalid-feedback"><?php echo e($message); ?></div><?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password_confirmation"><i class="fas fa-lock form-icon"></i> Konfirmasi Password</label>
|
||||
<input type="password" id="password_confirmation" name="password_confirmation" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group action-group">
|
||||
<button type="submit" class="btn btn-success btn-full hover-shadow">
|
||||
<i class="fas fa-paper-plane"></i> Daftarkan Admin
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p style="text-align: center; font-size: 0.9rem; margin-top: 20px;">
|
||||
Sudah punya akun? <a href="<?php echo e(route('admin.login')); ?>" class="link-primary">Login di sini</a>
|
||||
</p>
|
||||
</form>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('auth.auth_layout', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/auth/register.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-book-open"></i> Master Materi Al-Qur'an & Hadist</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(session('error')): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php echo e(session('error')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<form method="GET" action="<?php echo e(route('admin.materi.index')); ?>" class="filter-form-inline">
|
||||
<select name="kategori" class="form-control" style="width: 200px;">
|
||||
<option value="">Semua Kategori</option>
|
||||
<option value="Al-Qur'an" <?php echo e(request('kategori') == 'Al-Qur\'an' ? 'selected' : ''); ?>>Al-Qur'an</option>
|
||||
<option value="Hadist" <?php echo e(request('kategori') == 'Hadist' ? 'selected' : ''); ?>>Hadist</option>
|
||||
<option value="Materi Tambahan" <?php echo e(request('kategori') == 'Materi Tambahan' ? 'selected' : ''); ?>>Materi Tambahan</option>
|
||||
</select>
|
||||
|
||||
<select name="kelas" class="form-control" style="width: 180px;">
|
||||
<option value="">Semua Kelas</option>
|
||||
<option value="Lambatan" <?php echo e(request('kelas') == 'Lambatan' ? 'selected' : ''); ?>>Lambatan</option>
|
||||
<option value="Cepatan" <?php echo e(request('kelas') == 'Cepatan' ? 'selected' : ''); ?>>Cepatan</option>
|
||||
<option value="PB" <?php echo e(request('kelas') == 'PB' ? 'selected' : ''); ?>>PB</option>
|
||||
</select>
|
||||
|
||||
<input type="text" name="search" class="form-control" placeholder="Cari nama kitab..."
|
||||
value="<?php echo e(request('search')); ?>" style="width: 250px;">
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-search"></i> Filter
|
||||
</button>
|
||||
|
||||
<?php if(request()->anyFilled(['kategori', 'kelas', 'search'])): ?>
|
||||
<a href="<?php echo e(route('admin.materi.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="<?php echo e(route('admin.materi.create')); ?>" class="btn btn-success" style="margin-left: auto;">
|
||||
<i class="fas fa-plus"></i> Tambah Materi
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<?php if($materis->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">No</th>
|
||||
<th style="width: 10%;">ID Materi</th>
|
||||
<th style="width: 15%;">Kategori</th>
|
||||
<th style="width: 10%;">Kelas</th>
|
||||
<th style="width: 25%;">Nama Kitab</th>
|
||||
<th style="width: 15%;">Halaman</th>
|
||||
<th style="width: 10%;">Total Hal</th>
|
||||
<th class="text-center" style="width: 10%;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $materis; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $materi): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($materis->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($materi->id_materi); ?></strong></td>
|
||||
<td><?php echo $materi->kategori_badge; ?></td>
|
||||
<td><?php echo $materi->kelas_badge; ?></td>
|
||||
<td><?php echo e($materi->nama_kitab); ?></td>
|
||||
<td>
|
||||
<span class="badge badge-info">
|
||||
<?php echo e($materi->halaman_mulai); ?> - <?php echo e($materi->halaman_akhir); ?>
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<strong><?php echo e($materi->total_halaman); ?></strong> hal
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="btn-group">
|
||||
<a href="<?php echo e(route('admin.materi.show', $materi)); ?>"
|
||||
class="btn btn-sm btn-info" title="Detail">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.materi.edit', $materi)); ?>"
|
||||
class="btn btn-sm btn-warning" title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.materi.destroy', $materi)); ?>"
|
||||
method="POST" style="display: inline-block;"
|
||||
onsubmit="return confirm('Yakin ingin menghapus materi <?php echo e($materi->nama_kitab); ?>?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="Hapus">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($materis->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-book-open"></i>
|
||||
<h3>Belum Ada Data Materi</h3>
|
||||
<p>Silakan tambahkan materi pembelajaran Al-Qur'an, Hadist, atau Materi Tambahan.</p>
|
||||
<a href="<?php echo e(route('admin.materi.create')); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-plus"></i> Tambah Materi Pertama
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/materi/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -8,6 +8,12 @@
|
|||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
Selamat datang, <strong><?php echo e($data['nama_santri']); ?></strong> - Kelas <?php echo e($data['kelas']); ?>
|
||||
|
||||
<?php if($semesterAktif): ?>
|
||||
<span class="badge badge-success" style="margin-left: 10px;">
|
||||
<i class="fas fa-calendar-alt"></i> <?php echo e($semesterAktif->nama_semester); ?>
|
||||
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -34,65 +40,57 @@
|
|||
|
||||
<div class="row-cards">
|
||||
|
||||
<div class="card card-info">
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-book-quran"></i> Progres Al-Qur'an</h3>
|
||||
<div class="card-value"><?php echo e($data['progres_quran']); ?>%</div>
|
||||
<div class="card-icon"><i class="fas fa-book-quran"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?php echo e($data['progres_quran']); ?>%; background: var(--info-color);"></div>
|
||||
<div class="progress-fill" style="width: <?php echo e($data['progres_quran']); ?>%; background: var(--success-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-scroll"></i> Progres Hadist</h3>
|
||||
<div class="card-value"><?php echo e($data['progres_hadist']); ?>%</div>
|
||||
<div class="card-icon"><i class="fas fa-scroll"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?php echo e($data['progres_hadist']); ?>%; background: var(--info-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card card-warning">
|
||||
<h3><i class="fas fa-book"></i> Materi Tambahan</h3>
|
||||
<div class="card-value"><?php echo e($data['progres_materi_tambahan']); ?>%</div>
|
||||
<div class="card-icon"><i class="fas fa-book"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?php echo e($data['progres_materi_tambahan']); ?>%; background: var(--warning-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card card-primary">
|
||||
<h3><i class="fas fa-scroll"></i> Progres Hadist</h3>
|
||||
<div class="card-value"><?php echo e($data['progres_hadist']); ?>%</div>
|
||||
<div class="card-icon"><i class="fas fa-scroll"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" style="width: <?php echo e($data['progres_hadist']); ?>%; background: var(--primary-color);"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-wallet"></i> Saldo Uang Saku</h3>
|
||||
<div class="card-value"><?php echo e('Rp ' . number_format($data['saldo_uang_saku'], 0, ',', '.')); ?></div>
|
||||
<div class="card-value-small"><?php echo e('Rp ' . number_format($data['saldo_uang_saku'], 0, ',', '.')); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-wallet"></i></div>
|
||||
<div style="margin-top: 10px;">
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-sm btn-success" style="width: 100%; justify-content: center;">
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-sm btn-primary" style="width: 100%; justify-content: center;">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card card-<?php echo e($data['poin_pelanggaran'] > 0 ? 'danger' : 'warning'); ?>">
|
||||
<h3><i class="fas fa-exclamation-triangle"></i> Total Poin Pelanggaran</h3>
|
||||
<div class="card-value"><?php echo e($data['poin_pelanggaran']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-exclamation-triangle"></i></div>
|
||||
<?php if($data['poin_pelanggaran'] > 0): ?>
|
||||
<div style="margin-top: 10px;">
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-sm btn-danger" style="width: 100%; justify-content: center;">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div style="margin-top: 10px;">
|
||||
<span class="badge badge-success">
|
||||
<i class="fas fa-check-circle"></i> Tidak ada pelanggaran
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($beritaTerbaru->isNotEmpty()): ?>
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
||||
<h3 style="margin: 0; color: var(--primary-color);">
|
||||
<i class="fas fa-newspaper"></i> Berita Terbaru (7 Hari Terakhir)
|
||||
|
|
@ -129,62 +127,163 @@
|
|||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h3 style="margin: 0 0 20px 0; color: var(--primary-color);">
|
||||
<i class="fas fa-bolt"></i> Akses Cepat
|
||||
</h3>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
|
||||
|
||||
<a href="<?php echo e(route('santri.profil.index')); ?>" class="btn btn-primary hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-user" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Profil Saya</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="<?php echo e(route('santri.berita.index')); ?>" class="btn btn-info hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-newspaper" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Berita</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="<?php echo e(route('santri.uang-saku.index')); ?>" class="btn btn-success hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-wallet" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Uang Saku</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-danger hover-lift" style="padding: 15px; text-align: center;">
|
||||
<i class="fas fa-exclamation-circle" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Pelanggaran</span>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="<?php echo e(route('santri.kesehatan.index')); ?>" class="btn btn-<?php echo e(isset($statusKesehatan) && $statusKesehatan ? 'danger' : 'info'); ?> hover-lift" style="padding: 15px; text-align: center; position: relative;">
|
||||
<i class="fas fa-heartbeat" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Kesehatan</span>
|
||||
<?php if(isset($statusKesehatan) && $statusKesehatan): ?>
|
||||
<span class="badge badge-light" style="display: block; margin-top: 5px; font-size: 0.75rem; background: rgba(255,255,255,0.9); color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-circle"></i> Sedang Dirawat
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="<?php echo e(route('santri.kepulangan.index')); ?>" class="btn btn-<?php echo e(isset($kepulanganAktif) && $kepulanganAktif ? 'info' : 'primary'); ?> hover-lift" style="padding: 15px; text-align: center; position: relative;">
|
||||
<i class="fas fa-home" style="font-size: 1.5rem; display: block; margin-bottom: 8px;"></i>
|
||||
<span style="font-size: 0.9rem;">Kepulangan</span>
|
||||
<?php if(isset($kepulanganAktif) && $kepulanganAktif): ?>
|
||||
<span class="badge badge-light" style="display: block; margin-top: 5px; font-size: 0.75rem; background: rgba(255,255,255,0.9); color: var(--info-color);">
|
||||
<i class="fas fa-home"></i> Sedang Pulang
|
||||
</span>
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 15px;">
|
||||
<div style="flex: 1;">
|
||||
<h3 style="margin: 0 0 5px 0; color: var(--<?php echo e($data['poin_pelanggaran'] > 0 ? 'danger' : 'success'); ?>-color);">
|
||||
<i class="fas fa-exclamation-triangle"></i> Total Poin Pelanggaran: <strong><?php echo e($data['poin_pelanggaran']); ?></strong>
|
||||
</h3>
|
||||
<?php if($data['poin_pelanggaran'] > 0): ?>
|
||||
<p style="margin: 0; color: var(--text-light); font-size: 0.9rem;">
|
||||
Anda memiliki <?php echo e($data['poin_pelanggaran']); ?> poin pelanggaran. Jaga kedisiplinan!
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p style="margin: 0; color: var(--text-light); font-size: 0.9rem;">
|
||||
<i class="fas fa-check-circle" style="color: var(--success-color);"></i> Alhamdulillah, tidak ada catatan pelanggaran.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-<?php echo e($data['poin_pelanggaran'] > 0 ? 'danger' : 'success'); ?>">
|
||||
<i class="fas fa-eye"></i> Lihat Riwayat
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-top: 20px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
<?php if($capaianPerMateri->count() > 0 || array_sum($distribusiStatus) > 0): ?>
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-line"></i> Visualisasi Capaian Pembelajaran
|
||||
</h3>
|
||||
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 25px; margin-bottom: 30px;">
|
||||
|
||||
|
||||
<?php if(array_sum($distribusiStatus) > 0): ?>
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-md); border: 2px solid var(--primary-light);">
|
||||
<h4 style="margin: 0 0 20px 0; font-size: 1.1rem; color: var(--text-color); text-align: center; font-weight: 700;">
|
||||
<i class="fas fa-chart-pie"></i> Distribusi Status Pembelajaran
|
||||
</h4>
|
||||
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 25px; flex-wrap: wrap;">
|
||||
|
||||
<div style="flex: 1; min-width: 250px; max-width: 350px;">
|
||||
<canvas id="chartPieStatus" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 12px;">
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #6FBA9D 0%, #5EA98C 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Selesai (100%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);"><?php echo e($distribusiStatus['selesai']); ?> materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #81C6E8 0%, #6AB0D4 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Hampir Selesai (75-99%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);"><?php echo e($distribusiStatus['hampir_selesai']); ?> materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #FFD56B 0%, #E6B85C 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Sedang Berjalan (25-74%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);"><?php echo e($distribusiStatus['sedang_berjalan']); ?> materi</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 10px;">
|
||||
<div style="width: 24px; height: 24px; background: linear-gradient(135deg, #FF8B94 0%, #E77580 100%); border-radius: 4px; flex-shrink: 0;"></div>
|
||||
<div style="flex: 1;">
|
||||
<div style="font-weight: 700; color: var(--text-color); font-size: 0.9rem;">Baru Dimulai (0-24%)</div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-light);"><?php echo e($distribusiStatus['baru_dimulai']); ?> materi</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #f0f0f0; display: flex; justify-content: space-between; gap: 8px; flex-wrap: wrap;">
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--success-color); line-height: 1;"><?php echo e($distribusiStatus['selesai']); ?></div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Selesai</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #E3F2FD 0%, #D1E9F9 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--info-color); line-height: 1;"><?php echo e($distribusiStatus['hampir_selesai']); ?></div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Hampir Selesai</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #FFF8E1 0%, #FFF3CD 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--warning-color); line-height: 1;"><?php echo e($distribusiStatus['sedang_berjalan']); ?></div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Sedang Berjalan</div>
|
||||
</div>
|
||||
<div style="flex: 1; min-width: 70px; text-align: center; padding: 10px 8px; background: linear-gradient(135deg, #FFE8EA 0%, #FFD5D8 100%); border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05);">
|
||||
<div style="font-size: 1.3rem; font-weight: 700; color: var(--danger-color); line-height: 1;"><?php echo e($distribusiStatus['baru_dimulai']); ?></div>
|
||||
<div style="font-size: 0.75rem; color: var(--text-color); font-weight: 600; margin-top: 4px; line-height: 1.2;">Baru Dimulai</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-md); border: 2px solid var(--primary-light);">
|
||||
<h4 style="margin: 0 0 20px 0; font-size: 1.1rem; color: var(--text-color); text-align: center; font-weight: 700;">
|
||||
<i class="fas fa-chart-line"></i> Perbandingan Progress Kategori
|
||||
</h4>
|
||||
<div style="max-width: 450px; margin: 0 auto;">
|
||||
<canvas id="chartLineKategori" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
<div style="margin-top: 20px; display: flex; justify-content: center; gap: 20px; flex-wrap: wrap;">
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--success-color), #5EA98C); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(111, 186, 157, 0.3);">
|
||||
<?php echo e($data['progres_quran']); ?>%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Al-Qur'an</div>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--info-color), #6AB0D4); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(129, 198, 232, 0.3);">
|
||||
<?php echo e($data['progres_hadist']); ?>%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Hadist</div>
|
||||
</div>
|
||||
<div style="text-align: center;">
|
||||
<div style="width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, var(--warning-color), #E6B85C); display: flex; align-items: center; justify-content: center; margin: 0 auto 8px; color: white; font-size: 1.1rem; font-weight: 700; box-shadow: 0 4px 8px rgba(255, 213, 107, 0.3);">
|
||||
<?php echo e($data['progres_materi_tambahan']); ?>%
|
||||
</div>
|
||||
<div style="font-size: 0.85rem; color: var(--text-color); font-weight: 600;">Materi Tambahan</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<?php if($capaianPerMateri->count() > 0): ?>
|
||||
<div class="content-box" style="margin-top: 25px;">
|
||||
<h3 style="margin-bottom: 20px; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-bar"></i> Progress per Materi (Top 10)
|
||||
</h3>
|
||||
|
||||
<div style="background: white; padding: 25px; border-radius: var(--border-radius); box-shadow: var(--shadow-sm); border: 2px solid var(--primary-light);">
|
||||
<canvas id="chartBarMateri" style="max-height: 450px;"></canvas>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 20px; text-align: center;">
|
||||
<a href="<?php echo e(route('santri.capaian.index')); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-list"></i> Lihat Semua Capaian Detail
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-top: 25px; background: linear-gradient(135deg, #E8F7F2 0%, #D4F1E3 100%); border: 2px solid var(--primary-color);">
|
||||
<h4 style="margin: 0 0 15px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-lightbulb"></i> Tips Hari Ini
|
||||
</h4>
|
||||
|
|
@ -194,5 +293,268 @@
|
|||
untuk mengetahui peraturan yang berlaku.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 1: Distribusi Status (PIE CHART)
|
||||
// ============================================
|
||||
<?php if(array_sum($distribusiStatus) > 0): ?>
|
||||
const ctxPieStatus = document.getElementById('chartPieStatus');
|
||||
if (ctxPieStatus) {
|
||||
new Chart(ctxPieStatus.getContext('2d'), {
|
||||
type: 'pie',
|
||||
data: {
|
||||
// labels: ['Selesai (100%)', 'Hampir Selesai (75-99%)', 'Sedang Berjalan (25-74%)', 'Baru Dimulai (0-24%)'],
|
||||
datasets: [{
|
||||
data: [
|
||||
<?php echo e($distribusiStatus['selesai']); ?>,
|
||||
<?php echo e($distribusiStatus['hampir_selesai']); ?>,
|
||||
<?php echo e($distribusiStatus['sedang_berjalan']); ?>,
|
||||
<?php echo e($distribusiStatus['baru_dimulai']); ?>
|
||||
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.9)',
|
||||
'rgba(129, 198, 232, 0.9)',
|
||||
'rgba(255, 213, 107, 0.9)',
|
||||
'rgba(255, 139, 148, 0.9)',
|
||||
],
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 15,
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
const label = context.label || '';
|
||||
const value = context.parsed || 0;
|
||||
const total = context.dataset.data.reduce((a, b) => a + b, 0);
|
||||
const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
|
||||
return label + ': ' + value + ' materi (' + percentage + '%)';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 2: Perbandingan Kategori (LINE CHART)
|
||||
// ============================================
|
||||
const ctxLineKategori = document.getElementById('chartLineKategori');
|
||||
if (ctxLineKategori) {
|
||||
new Chart(ctxLineKategori.getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ['Al-Qur\'an', 'Hadist', 'Materi Tambahan'],
|
||||
datasets: [{
|
||||
label: 'Progress (%)',
|
||||
data: [
|
||||
<?php echo e($data['progres_quran']); ?>,
|
||||
<?php echo e($data['progres_hadist']); ?>,
|
||||
<?php echo e($data['progres_materi_tambahan']); ?>
|
||||
|
||||
],
|
||||
backgroundColor: 'rgba(111, 186, 157, 0.2)',
|
||||
borderColor: 'rgba(111, 186, 157, 1)',
|
||||
borderWidth: 4,
|
||||
pointBackgroundColor: [
|
||||
'rgba(111, 186, 157, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(255, 213, 107, 1)'
|
||||
],
|
||||
pointBorderColor: '#fff',
|
||||
pointBorderWidth: 3,
|
||||
pointRadius: 8,
|
||||
pointHoverRadius: 10,
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
ticks: {
|
||||
stepSize: 20,
|
||||
callback: function(value) {
|
||||
return value + '%';
|
||||
},
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: 'rgba(0, 0, 0, 0.05)'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Progress: ' + context.parsed.y.toFixed(1) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// GRAFIK 3: Progress per Materi (BAR CHART - Vertikal)
|
||||
// ============================================
|
||||
<?php if($capaianPerMateri->count() > 0): ?>
|
||||
const ctxBarMateri = document.getElementById('chartBarMateri');
|
||||
if (ctxBarMateri) {
|
||||
new Chart(ctxBarMateri.getContext('2d'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
<?php $__currentLoopData = $capaianPerMateri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
'<?php echo e(Str::limit($item->materi->nama_kitab, 30)); ?>',
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
datasets: [{
|
||||
label: 'Progress (%)',
|
||||
data: [
|
||||
<?php $__currentLoopData = $capaianPerMateri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php echo e($item->persentase); ?>,
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
backgroundColor: [
|
||||
<?php $__currentLoopData = $capaianPerMateri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($item->materi->kategori == 'Al-Qur\'an'): ?>
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
<?php elseif($item->materi->kategori == 'Hadist'): ?>
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
<?php else: ?>
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
borderColor: [
|
||||
<?php $__currentLoopData = $capaianPerMateri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<?php if($item->materi->kategori == 'Al-Qur\'an'): ?>
|
||||
'rgba(111, 186, 157, 1)',
|
||||
<?php elseif($item->materi->kategori == 'Hadist'): ?>
|
||||
'rgba(129, 198, 232, 1)',
|
||||
<?php else: ?>
|
||||
'rgba(255, 213, 107, 1)',
|
||||
<?php endif; ?>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
],
|
||||
borderWidth: 2,
|
||||
borderRadius: 8,
|
||||
borderSkipped: false
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return 'Progress: ' + context.parsed.y.toFixed(1) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
ticks: {
|
||||
stepSize: 10,
|
||||
callback: function(value) {
|
||||
return value + '%';
|
||||
},
|
||||
font: {
|
||||
size: 12,
|
||||
weight: '600'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: 'rgba(0, 0, 0, 0.05)'
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Persentase (%)',
|
||||
font: {
|
||||
size: 14,
|
||||
weight: 'bold'
|
||||
}
|
||||
}
|
||||
},
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
size: 11
|
||||
},
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
},
|
||||
grid: {
|
||||
display: false
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Materi',
|
||||
font: {
|
||||
size: 14,
|
||||
weight: 'bold'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/dashboardSantri.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-plus-circle"></i> Tambah Transaksi Uang Saku</h2>
|
||||
</div>
|
||||
|
||||
<div class="form-container">
|
||||
<form action="<?php echo e(route('admin.uang-saku.store')); ?>" method="POST" id="transaksiForm">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="id_santri">
|
||||
<i class="fas fa-user form-icon"></i>
|
||||
Pilih Santri <span style="color: red;">*</span>
|
||||
</label>
|
||||
<select name="id_santri" id="id_santri" class="form-control <?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Santri --</option>
|
||||
<?php $__currentLoopData = $santriList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($santri->id_santri); ?>"
|
||||
<?php echo e((old('id_santri', request('id_santri')) == $santri->id_santri) ? 'selected' : ''); ?>>
|
||||
<?php echo e($santri->id_santri); ?> - <?php echo e($santri->nama_lengkap); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="jenis_transaksi">
|
||||
<i class="fas fa-exchange-alt form-icon"></i>
|
||||
Jenis Transaksi <span style="color: red;">*</span>
|
||||
</label>
|
||||
<select name="jenis_transaksi" id="jenis_transaksi" class="form-control <?php $__errorArgs = ['jenis_transaksi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Jenis --</option>
|
||||
<option value="pemasukan" <?php echo e(old('jenis_transaksi') == 'pemasukan' ? 'selected' : ''); ?>>
|
||||
Pemasukan (Terima Uang Saku)
|
||||
</option>
|
||||
<option value="pengeluaran" <?php echo e(old('jenis_transaksi') == 'pengeluaran' ? 'selected' : ''); ?>>
|
||||
Pengeluaran (Gunakan Uang Saku)
|
||||
</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['jenis_transaksi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="nominal">
|
||||
<i class="fas fa-money-bill-wave form-icon"></i>
|
||||
Nominal (Rp) <span style="color: red;">*</span>
|
||||
</label>
|
||||
<input type="number" name="nominal" id="nominal" class="form-control <?php $__errorArgs = ['nominal'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('nominal')); ?>" placeholder="Contoh: 50000" min="1" step="1" required>
|
||||
<?php $__errorArgs = ['nominal'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">Masukkan nominal tanpa titik atau koma</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="tanggal_transaksi">
|
||||
<i class="fas fa-calendar form-icon"></i>
|
||||
Tanggal Transaksi <span style="color: red;">*</span>
|
||||
</label>
|
||||
<input type="date" name="tanggal_transaksi" id="tanggal_transaksi"
|
||||
class="form-control <?php $__errorArgs = ['tanggal_transaksi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('tanggal_transaksi', date('Y-m-d'))); ?>" required>
|
||||
<?php $__errorArgs = ['tanggal_transaksi'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="keterangan">
|
||||
<i class="fas fa-sticky-note form-icon"></i>
|
||||
Keterangan
|
||||
</label>
|
||||
<textarea name="keterangan" id="keterangan" class="form-control <?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
rows="4" placeholder="Contoh: Uang saku bulan Januari 2025"><?php echo e(old('keterangan')); ?></textarea>
|
||||
<?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">Opsional - Jelaskan detail transaksi</small>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-success hover-lift">
|
||||
<i class="fas fa-save"></i> Simpan Transaksi
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.uang-saku.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Format nominal input (tambah separator ribuan saat blur)
|
||||
document.getElementById('nominal').addEventListener('blur', function(e) {
|
||||
if (this.value) {
|
||||
const value = parseInt(this.value.replace(/\D/g, ''));
|
||||
if (!isNaN(value)) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Validasi form sebelum submit
|
||||
document.getElementById('transaksiForm').addEventListener('submit', function(e) {
|
||||
const nominal = document.getElementById('nominal').value;
|
||||
|
||||
if (nominal && parseInt(nominal) < 1) {
|
||||
e.preventDefault();
|
||||
alert('Nominal harus lebih dari 0');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/uang-saku/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Tambah Riwayat Pelanggaran'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-plus-circle"></i> Tambah Riwayat Pelanggaran</h2>
|
||||
</div>
|
||||
|
||||
<!-- Breadcrumb -->
|
||||
<div style="margin-bottom: 20px;">
|
||||
<nav style="display: flex; align-items: center; gap: 8px; color: var(--text-light); font-size: 0.9em;">
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>" style="color: var(--primary-color); text-decoration: none;">
|
||||
<i class="fas fa-history"></i> Riwayat Pelanggaran
|
||||
</a>
|
||||
<i class="fas fa-chevron-right" style="font-size: 0.7em;"></i>
|
||||
<span>Tambah</span>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 25px;">
|
||||
<h3 style="margin: 0; color: var(--primary-color);">
|
||||
<i class="fas fa-edit"></i> Form Tambah Riwayat
|
||||
</h3>
|
||||
<div style="background: var(--primary-light); padding: 10px 20px; border-radius: var(--border-radius-sm);">
|
||||
<small style="color: var(--text-light);">ID Riwayat Berikutnya:</small>
|
||||
<strong style="color: var(--primary-dark); font-size: 1.1em;"><?php echo e($nextIdRiwayat); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="<?php echo e(route('admin.riwayat-pelanggaran.store')); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
|
||||
<!-- Santri -->
|
||||
<div class="form-group">
|
||||
<label for="id_santri">
|
||||
<i class="fas fa-user form-icon"></i>
|
||||
Santri <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<select name="id_santri"
|
||||
id="id_santri"
|
||||
class="form-control <?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
required>
|
||||
<option value="">-- Pilih Santri --</option>
|
||||
<?php $__currentLoopData = $santriList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($santri->id_santri); ?>" <?php echo e(old('id_santri') == $santri->id_santri ? 'selected' : ''); ?>>
|
||||
<?php echo e($santri->nama_lengkap); ?> - <?php echo e($santri->kelas); ?> (<?php echo e($santri->id_santri); ?>)
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<!-- Tanggal -->
|
||||
<div class="form-group">
|
||||
<label for="tanggal">
|
||||
<i class="fas fa-calendar form-icon"></i>
|
||||
Tanggal Pelanggaran <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<input type="date"
|
||||
name="tanggal"
|
||||
id="tanggal"
|
||||
class="form-control <?php $__errorArgs = ['tanggal'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('tanggal', date('Y-m-d'))); ?>"
|
||||
required>
|
||||
<?php $__errorArgs = ['tanggal'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kategori Pelanggaran -->
|
||||
<div class="form-group">
|
||||
<label for="id_kategori">
|
||||
<i class="fas fa-tags form-icon"></i>
|
||||
Kategori Pelanggaran <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<select name="id_kategori"
|
||||
id="id_kategori"
|
||||
class="form-control <?php $__errorArgs = ['id_kategori'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
required>
|
||||
<option value="">-- Pilih Kategori Pelanggaran --</option>
|
||||
<?php $__currentLoopData = $kategoriList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $kategori): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($kategori->id_kategori); ?>"
|
||||
data-poin="<?php echo e($kategori->poin); ?>"
|
||||
<?php echo e(old('id_kategori') == $kategori->id_kategori ? 'selected' : ''); ?>>
|
||||
<?php echo e($kategori->nama_pelanggaran); ?> - <?php echo e($kategori->poin); ?> Poin (<?php echo e($kategori->id_kategori); ?>)
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['id_kategori'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
|
||||
<!-- Preview Poin -->
|
||||
<div id="poin-preview" style="display: none; margin-top: 12px; padding: 12px; background: var(--danger-color); color: white; border-radius: var(--border-radius-sm); text-align: center;">
|
||||
<i class="fas fa-fire"></i>
|
||||
<strong>Poin yang akan ditambahkan: <span id="poin-value">0</span> Poin</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Keterangan -->
|
||||
<div class="form-group">
|
||||
<label for="keterangan">
|
||||
<i class="fas fa-comment form-icon"></i>
|
||||
Keterangan Tambahan
|
||||
</label>
|
||||
<textarea name="keterangan"
|
||||
id="keterangan"
|
||||
rows="4"
|
||||
class="form-control <?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
placeholder="Jelaskan detail pelanggaran (opsional)"><?php echo e(old('keterangan')); ?></textarea>
|
||||
<?php $__errorArgs = ['keterangan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<span class="form-text">Maksimal 1000 karakter</span>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Simpan Riwayat
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.riwayat-pelanggaran.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Preview poin saat kategori dipilih
|
||||
document.getElementById('id_kategori').addEventListener('change', function() {
|
||||
const selectedOption = this.options[this.selectedIndex];
|
||||
const poin = selectedOption.getAttribute('data-poin');
|
||||
const preview = document.getElementById('poin-preview');
|
||||
const poinValue = document.getElementById('poin-value');
|
||||
|
||||
if (poin) {
|
||||
poinValue.textContent = poin;
|
||||
preview.style.display = 'block';
|
||||
} else {
|
||||
preview.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger change event jika ada old value
|
||||
if (document.getElementById('id_kategori').value) {
|
||||
document.getElementById('id_kategori').dispatchEvent(new Event('change'));
|
||||
}
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/riwayat_pelanggaran/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Riwayat Kepulangan'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-home"></i> Riwayat Kepulangan</h2>
|
||||
<p style="margin: 5px 0 0 0; color: var(--text-light);">
|
||||
Riwayat izin pulang <strong><?php echo e($santri->nama_lengkap); ?></strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
<h3><i class="fas fa-clipboard-list"></i> Total Pengajuan</h3>
|
||||
<div class="card-value"><?php echo e($statistik['total_izin']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-clipboard-list"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Tahun <?php echo e($tahunSekarang); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-success">
|
||||
<h3><i class="fas fa-check-circle"></i> Disetujui</h3>
|
||||
<div class="card-value"><?php echo e($statistik['disetujui']); ?></div>
|
||||
<div class="card-icon"><i class="fas fa-check-circle"></i></div>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Izin diterima
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card card-<?php echo e($statistik['over_limit'] ? 'danger' : 'primary'); ?>">
|
||||
<h3><i class="fas fa-calendar-alt"></i> Total Hari Pulang</h3>
|
||||
<div class="card-value"><?php echo e($statistik['total_hari']); ?> Hari</div>
|
||||
<div class="card-icon"><i class="fas fa-calendar-alt"></i></div>
|
||||
<?php if($statistik['over_limit']): ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-triangle"></i> Melebihi batas!
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Dari kuota 12 hari
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="card card-<?php echo e($statistik['sisa_kuota'] > 0 ? 'warning' : 'danger'); ?>">
|
||||
<h3><i class="fas fa-hourglass-half"></i> Sisa Kuota</h3>
|
||||
<div class="card-value"><?php echo e($statistik['sisa_kuota']); ?> Hari</div>
|
||||
<div class="card-icon"><i class="fas fa-hourglass-half"></i></div>
|
||||
<?php if($statistik['menunggu'] > 0): ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--warning-color);">
|
||||
<i class="fas fa-clock"></i> <?php echo e($statistik['menunggu']); ?> menunggu
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p style="margin-top: 10px; font-size: 0.85rem; color: var(--text-light);">
|
||||
Kuota tersisa
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($statistik['over_limit']): ?>
|
||||
<div class="alert alert-danger" style="margin-top: 20px;">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<strong>Peringatan:</strong> Anda telah melebihi batas kuota kepulangan (12 hari/tahun).
|
||||
Total hari pulang Anda tahun ini: <strong><?php echo e($statistik['total_hari']); ?> hari</strong>.
|
||||
</div>
|
||||
<?php elseif($statistik['sisa_kuota'] <= 3 && $statistik['sisa_kuota'] > 0): ?>
|
||||
<div class="alert alert-warning" style="margin-top: 20px;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Perhatian:</strong> Sisa kuota kepulangan Anda tinggal <strong><?php echo e($statistik['sisa_kuota']); ?> hari</strong>.
|
||||
Gunakan dengan bijak.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<form method="GET" class="filter-form-inline">
|
||||
<select name="tahun" class="form-control">
|
||||
<?php $__currentLoopData = $tahunOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $year): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($year); ?>" <?php echo e($tahunSekarang == $year ? 'selected' : ''); ?>>
|
||||
Tahun <?php echo e($year); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
|
||||
<select name="status" class="form-control">
|
||||
<option value="">Semua Status</option>
|
||||
<?php $__currentLoopData = $statusOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $value => $label): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($value); ?>" <?php echo e(request('status') == $value ? 'selected' : ''); ?>>
|
||||
<?php echo e($label); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
|
||||
<a href="<?php echo e(route('santri.kepulangan.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-sync"></i> Reset
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($riwayatKepulangan->isEmpty()): ?>
|
||||
<div class="empty-state" style="margin-top: 20px;">
|
||||
<i class="fas fa-home"></i>
|
||||
<h3>Belum Ada Riwayat Kepulangan</h3>
|
||||
<p>Anda belum pernah mengajukan izin kepulangan pada periode yang dipilih.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="content-box" style="margin-top: 20px;">
|
||||
<h3 style="margin: 0 0 15px 0; color: var(--primary-color);">
|
||||
<i class="fas fa-list"></i> Daftar Riwayat (<?php echo e($riwayatKepulangan->total()); ?> data)
|
||||
</h3>
|
||||
|
||||
<div style="display: flex; flex-direction: column; gap: 15px;">
|
||||
<?php $__currentLoopData = $riwayatKepulangan; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<a href="<?php echo e(route('santri.kepulangan.show', $item->id_kepulangan)); ?>"
|
||||
style="display: flex; gap: 15px; padding: 15px; background: linear-gradient(135deg, #FFFFFF 0%, #FEFFFE 100%); border-radius: var(--border-radius-sm); border-left: 4px solid
|
||||
<?php if($item->status == 'Menunggu'): ?> var(--warning-color)
|
||||
<?php elseif($item->status == 'Disetujui'): ?> var(--success-color)
|
||||
<?php elseif($item->status == 'Ditolak'): ?> var(--danger-color)
|
||||
<?php else: ?> var(--text-light) <?php endif; ?>
|
||||
; text-decoration: none; transition: var(--transition-base); position: relative;"
|
||||
onmouseover="this.style.boxShadow='var(--shadow-md)'; this.style.transform='translateX(5px)';"
|
||||
onmouseout="this.style.boxShadow='none'; this.style.transform='translateX(0)';">
|
||||
|
||||
|
||||
<div style="flex-shrink: 0; width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background:
|
||||
<?php if($item->status == 'Menunggu'): ?> linear-gradient(135deg, #FFF8E1, #FFF3CD)
|
||||
<?php elseif($item->status == 'Disetujui'): ?> linear-gradient(135deg, #E8F7F2, #D4F1E3)
|
||||
<?php elseif($item->status == 'Ditolak'): ?> linear-gradient(135deg, #FFE8EA, #FFD5D8)
|
||||
<?php else: ?> linear-gradient(135deg, #E2E3E5, #D6D8DB) <?php endif; ?>
|
||||
;">
|
||||
<i class="fas
|
||||
<?php if($item->status == 'Menunggu'): ?> fa-clock
|
||||
<?php elseif($item->status == 'Disetujui'): ?> fa-check-circle
|
||||
<?php elseif($item->status == 'Ditolak'): ?> fa-times-circle
|
||||
<?php else: ?> fa-flag-checkered <?php endif; ?>
|
||||
" style="font-size: 1.8rem; color:
|
||||
<?php if($item->status == 'Menunggu'): ?> var(--warning-color)
|
||||
<?php elseif($item->status == 'Disetujui'): ?> var(--success-color)
|
||||
<?php elseif($item->status == 'Ditolak'): ?> var(--danger-color)
|
||||
<?php else: ?> var(--text-light) <?php endif; ?>
|
||||
;"></i>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="flex: 1; display: flex; flex-direction: column; justify-content: space-between; min-width: 0;">
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 8px;">
|
||||
<h3 style="margin: 0; font-size: 1rem; font-weight: 600; color: var(--text-color);">
|
||||
<?php echo e($item->alasan); ?>
|
||||
|
||||
</h3>
|
||||
<span class="badge badge-<?php echo e($item->status == 'Menunggu' ? 'warning' :
|
||||
($item->status == 'Disetujui' ? 'success' :
|
||||
($item->status == 'Ditolak' ? 'danger' : 'secondary'))); ?>">
|
||||
<?php echo e($item->status); ?>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p style="margin: 0 0 8px 0; font-size: 0.9rem; color: var(--text-light);">
|
||||
<i class="fas fa-code"></i> <?php echo e($item->id_kepulangan); ?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 15px; font-size: 0.85rem; color: var(--text-light);">
|
||||
<span>
|
||||
<i class="fas fa-calendar-alt"></i> <?php echo e($item->tanggal_pulang_formatted); ?> - <?php echo e($item->tanggal_kembali_formatted); ?>
|
||||
|
||||
</span>
|
||||
<span class="badge badge-info badge-sm">
|
||||
<i class="fas fa-clock"></i> <?php echo e($item->durasi_izin); ?> hari
|
||||
</span>
|
||||
<?php if($item->status == 'Disetujui'): ?>
|
||||
<?php if($item->is_aktif): ?>
|
||||
<span class="badge badge-success badge-sm">
|
||||
<i class="fas fa-home"></i> Sedang Pulang
|
||||
</span>
|
||||
<?php elseif($item->is_terlambat): ?>
|
||||
<span class="badge badge-danger badge-sm">
|
||||
<i class="fas fa-exclamation-triangle"></i> Terlambat Kembali
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="flex-shrink: 0; display: flex; align-items: center;">
|
||||
<i class="fas fa-chevron-right" style="color: var(--text-light);"></i>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 25px;">
|
||||
<?php echo e($riwayatKepulangan->links()); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="info-box" style="margin-top: 20px;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Info:</strong> Kuota kepulangan maksimal <strong>12 hari per tahun</strong>.
|
||||
Pastikan Anda merencanakan kepulangan dengan bijak agar tidak melebihi batas kuota.
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 20px; text-align: center;">
|
||||
<a href="<?php echo e(route('santri.dashboard')); ?>" class="btn btn-secondary hover-lift">
|
||||
<i class="fas fa-home"></i> Kembali ke Dashboard
|
||||
</a>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/kepulangan/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -20,10 +20,22 @@
|
|||
<div class="detail-header">
|
||||
<div style="display: flex; align-items: center; gap: 20px;">
|
||||
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
<?php if($santri->foto && file_exists(public_path('storage/' . $santri->foto))): ?>
|
||||
<img src="<?php echo e(asset('storage/' . $santri->foto)); ?>"
|
||||
alt="Foto <?php echo e($santri->nama_lengkap); ?>"
|
||||
style="width: 80px; height: 80px; border-radius: 50%; object-fit: cover; border: 3px solid var(--primary-color); flex-shrink: 0;"
|
||||
loading="lazy"
|
||||
onerror="this.onerror=null; this.style.display='none'; this.nextElementSibling.style.display='flex';">
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg" style="display: none;">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="santri-avatar-initial santri-avatar-initial-lg">
|
||||
<?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div>
|
||||
<h3 style="margin: 0; font-size: 1.8rem; color: var(--text-color);">
|
||||
|
|
@ -153,7 +165,7 @@
|
|||
<div style="margin-top: 30px; padding: 20px; background: var(--primary-light); border-radius: var(--border-radius-sm); border-left: 4px solid var(--primary-color);">
|
||||
<p style="margin: 0; color: var(--text-color); line-height: 1.6;">
|
||||
<i class="fas fa-info-circle" style="color: var(--primary-color);"></i>
|
||||
<strong>Catatan:</strong> Jika ada data yang perlu diperbarui selain alamat dan nomor HP orang tua, silakan hubungi admin atau pengurus pesantren.
|
||||
<strong>Catatan:</strong> Jika ada data yang perlu diperbarui termasuk foto profil, silakan hubungi admin atau pengurus pesantren.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-calendar-alt"></i> Detail Kegiatan</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div class="detail-header">
|
||||
<h3><?php echo e($kegiatan->nama_kegiatan); ?></h3>
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.kegiatan.edit', $kegiatan)); ?>" class="btn btn-warning">
|
||||
<i class="fas fa-edit"></i> Edit
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.kegiatan.destroy', $kegiatan)); ?>" method="POST" style="display: inline;" onsubmit="return confirm('Yakin ingin menghapus kegiatan ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="fas fa-trash"></i> Hapus
|
||||
</button>
|
||||
</form>
|
||||
<a href="<?php echo e(route('admin.kegiatan.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h4><i class="fas fa-info-circle"></i> Informasi Kegiatan</h4>
|
||||
<table class="detail-table">
|
||||
<tr>
|
||||
<th>ID Kegiatan</th>
|
||||
<td><strong><?php echo e($kegiatan->kegiatan_id); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Kategori</th>
|
||||
<td>
|
||||
<span class="badge badge-primary badge-lg"><?php echo e($kegiatan->kategori->nama_kategori); ?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Nama Kegiatan</th>
|
||||
<td><strong><?php echo e($kegiatan->nama_kegiatan); ?></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Hari</th>
|
||||
<td><span class="badge badge-info badge-lg"><?php echo e($kegiatan->hari); ?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Waktu Pelaksanaan</th>
|
||||
<td>
|
||||
<i class="fas fa-clock" style="color: var(--primary-color);"></i>
|
||||
<?php echo e(date('H:i', strtotime($kegiatan->waktu_mulai))); ?> - <?php echo e(date('H:i', strtotime($kegiatan->waktu_selesai))); ?> WIB
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Materi/Topik</th>
|
||||
<td><?php echo e($kegiatan->materi ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Keterangan</th>
|
||||
<td><?php echo e($kegiatan->keterangan ?? '-'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Dibuat Pada</th>
|
||||
<td><?php echo e($kegiatan->created_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Terakhir Diubah</th>
|
||||
<td><?php echo e($kegiatan->updated_at->format('d F Y, H:i')); ?> WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/data/show.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,379 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-chart-pie"></i> Dashboard Capaian Al-Qur'an & Hadist</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<form method="GET" action="<?php echo e(route('admin.capaian.dashboard')); ?>" class="filter-form-inline">
|
||||
<select name="id_santri" class="form-control" style="width: 250px;">
|
||||
<option value="">Semua Santri</option>
|
||||
<?php $__currentLoopData = $santris; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $santri): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($santri->id_santri); ?>" <?php echo e($idSantri == $santri->id_santri ? 'selected' : ''); ?>>
|
||||
<?php echo e($santri->nama_lengkap); ?> (<?php echo e($santri->kelas); ?>)
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
|
||||
<select name="id_semester" class="form-control" style="width: 200px;">
|
||||
<option value="">Semua Semester</option>
|
||||
<?php $__currentLoopData = $semesters; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $semester): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($semester->id_semester); ?>" <?php echo e($selectedSemester == $semester->id_semester ? 'selected' : ''); ?>>
|
||||
<?php echo e($semester->nama_semester); ?> <?php if($semester->is_active): ?> ★ <?php endif; ?>
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
|
||||
<select name="kelas" class="form-control" style="width: 150px;">
|
||||
<option value="">Semua Kelas</option>
|
||||
<option value="Lambatan" <?php echo e($kelas == 'Lambatan' ? 'selected' : ''); ?>>Lambatan</option>
|
||||
<option value="Cepatan" <?php echo e($kelas == 'Cepatan' ? 'selected' : ''); ?>>Cepatan</option>
|
||||
<option value="PB" <?php echo e($kelas == 'PB' ? 'selected' : ''); ?>>PB</option>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-filter"></i> Filter
|
||||
</button>
|
||||
|
||||
<?php if($idSantri || $kelas): ?>
|
||||
<a href="<?php echo e(route('admin.capaian.dashboard')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-redo"></i> Reset
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<div class="card card-info">
|
||||
<h3>Total Capaian</h3>
|
||||
<div class="card-value"><?php echo e($totalCapaian); ?></div>
|
||||
<p class="text-muted">Data capaian tercatat</p>
|
||||
<i class="fas fa-clipboard-list card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-success">
|
||||
<h3>Total Santri</h3>
|
||||
<div class="card-value"><?php echo e($totalSantri); ?></div>
|
||||
<p class="text-muted">Santri aktif dengan capaian</p>
|
||||
<i class="fas fa-users card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-primary">
|
||||
<h3>Rata-rata Progress</h3>
|
||||
<div class="card-value"><?php echo e(number_format($rataRataPersentase, 1)); ?>%</div>
|
||||
<p class="text-muted">Progress keseluruhan</p>
|
||||
<i class="fas fa-chart-line card-icon"></i>
|
||||
</div>
|
||||
<div class="card card-warning">
|
||||
<h3>Selesai 100%</h3>
|
||||
<div class="card-value"><?php echo e($capaianSelesai); ?></div>
|
||||
<p class="text-muted">Materi yang diselesaikan</p>
|
||||
<i class="fas fa-trophy card-icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-cards">
|
||||
<?php $__currentLoopData = $statistikKategori; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $kategori => $stats): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div class="card card-<?php echo e($kategori == 'Al-Qur\'an' ? 'primary' : ($kategori == 'Hadist' ? 'success' : 'info')); ?>">
|
||||
<h3><?php echo e($kategori); ?></h3>
|
||||
<div class="card-value-small"><?php echo e(number_format($stats['avg'], 1)); ?>%</div>
|
||||
<p class="text-muted">
|
||||
<?php echo e($stats['count']); ?> capaian | <?php echo e($stats['selesai']); ?> selesai
|
||||
</p>
|
||||
<i class="fas fa-<?php echo e($kategori == 'Al-Qur\'an' ? 'book-quran' : ($kategori == 'Hadist' ? 'scroll' : 'book')); ?> card-icon"></i>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
|
||||
|
||||
<div class="content-box">
|
||||
<h4 style="margin: 0 0 20px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-pie"></i> Progress per Kategori
|
||||
</h4>
|
||||
<canvas id="chartKategori" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box">
|
||||
<h4 style="margin: 0 0 20px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-bar"></i> Distribusi Progress Santri
|
||||
</h4>
|
||||
<canvas id="chartDistribusi" style="max-height: 300px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<h4 style="margin: 0 0 20px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-chart-line"></i> Trend Progress dari Waktu ke Waktu
|
||||
</h4>
|
||||
<canvas id="chartTrend" style="max-height: 250px;"></canvas>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content-box" style="margin-bottom: 20px;">
|
||||
<h4 style="margin: 0 0 20px 0; color: var(--primary-dark);">
|
||||
<i class="fas fa-trophy"></i> Top 10 Santri dengan Progress Tertinggi
|
||||
</h4>
|
||||
<?php if($topSantri->count() > 0): ?>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5%;">Rank</th>
|
||||
<th style="width: 10%;">NIS</th>
|
||||
<th style="width: 30%;">Nama Santri</th>
|
||||
<th style="width: 10%;">Kelas</th>
|
||||
<th style="width: 25%;">Rata-rata Progress</th>
|
||||
<th class="text-center" style="width: 20%;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $topSantri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<?php if($index < 3): ?>
|
||||
<span style="font-size: 1.5rem;">
|
||||
<?php if($index == 0): ?> 🥇
|
||||
<?php elseif($index == 1): ?> 🥈
|
||||
<?php else: ?> 🥉
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<strong><?php echo e($index + 1); ?></strong>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo e($item->santri->nis); ?></td>
|
||||
<td><strong><?php echo e($item->santri->nama_lengkap); ?></strong></td>
|
||||
<td><span class="badge badge-secondary"><?php echo e($item->santri->kelas); ?></span></td>
|
||||
<td>
|
||||
<div class="progress-bar" style="height: 25px;">
|
||||
<div class="progress-fill" style="width: <?php echo e($item->rata_rata); ?>%; background: linear-gradient(90deg, var(--primary-color), var(--success-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold;">
|
||||
<?php echo e(number_format($item->rata_rata, 1)); ?>%
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('admin.capaian.riwayat-santri', $item->id_santri)); ?>" class="btn btn-sm btn-info">
|
||||
<i class="fas fa-eye"></i> Lihat Detail
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
<p>Belum ada data untuk ditampilkan</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
<?php if($materiTerendah->count() > 0): ?>
|
||||
<div class="content-box">
|
||||
<h4 style="margin: 0 0 20px 0; color: var(--danger-color);">
|
||||
<i class="fas fa-exclamation-triangle"></i> Materi yang Perlu Perhatian (Progress < 50%)
|
||||
</h4>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 30%;">Nama Materi</th>
|
||||
<th style="width: 15%;">Kategori</th>
|
||||
<th style="width: 10%;">Kelas</th>
|
||||
<th style="width: 10%;">Jumlah Santri</th>
|
||||
<th style="width: 20%;">Rata-rata Progress</th>
|
||||
<th class="text-center" style="width: 15%;">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $materiTerendah; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><strong><?php echo e($item->materi->nama_kitab); ?></strong></td>
|
||||
<td><?php echo $item->materi->kategori_badge; ?></td>
|
||||
<td><?php echo $item->materi->kelas_badge; ?></td>
|
||||
<td class="text-center"><?php echo e($item->jumlah_santri); ?> santri</td>
|
||||
<td>
|
||||
<div class="progress-bar" style="height: 20px;">
|
||||
<div class="progress-fill" style="width: <?php echo e($item->rata_rata); ?>%; background: linear-gradient(90deg, var(--danger-color), var(--warning-color)); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 0.85rem;">
|
||||
<?php echo e(number_format($item->rata_rata, 1)); ?>%
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('admin.capaian.detail-materi', $item->id_materi)); ?>" class="btn btn-sm btn-warning">
|
||||
<i class="fas fa-eye"></i> Detail
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div style="margin-top: 30px; display: flex; gap: 10px; justify-content: center;">
|
||||
<a href="<?php echo e(route('admin.capaian.rekap-kelas')); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-table"></i> Rekap per Kelas
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.capaian.create')); ?>" class="btn btn-success">
|
||||
<i class="fas fa-plus"></i> Input Capaian Baru
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.materi.index')); ?>" class="btn btn-info">
|
||||
<i class="fas fa-book"></i> Master Materi
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script>
|
||||
// Chart 1: Pie Chart - Progress per Kategori
|
||||
const ctxKategori = document.getElementById('chartKategori').getContext('2d');
|
||||
const chartKategori = new Chart(ctxKategori, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Al-Qur\'an', 'Hadist', 'Materi Tambahan'],
|
||||
datasets: [{
|
||||
label: 'Rata-rata Progress (%)',
|
||||
data: [
|
||||
<?php echo e(number_format($statistikKategori['Al-Qur\'an']['avg'], 2)); ?>,
|
||||
<?php echo e(number_format($statistikKategori['Hadist']['avg'], 2)); ?>,
|
||||
<?php echo e(number_format($statistikKategori['Materi Tambahan']['avg'], 2)); ?>
|
||||
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(111, 186, 157, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(255, 213, 107, 1)',
|
||||
],
|
||||
borderWidth: 2
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
padding: 15,
|
||||
font: {
|
||||
size: 12
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return context.label + ': ' + context.parsed.toFixed(2) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Chart 2: Bar Chart - Distribusi Persentase
|
||||
const ctxDistribusi = document.getElementById('chartDistribusi').getContext('2d');
|
||||
const chartDistribusi = new Chart(ctxDistribusi, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['0-25%', '26-50%', '51-75%', '76-99%', '100%'],
|
||||
datasets: [{
|
||||
label: 'Jumlah Santri',
|
||||
data: [
|
||||
<?php echo e($distribusiPersentase['0-25%']); ?>,
|
||||
<?php echo e($distribusiPersentase['26-50%']); ?>,
|
||||
<?php echo e($distribusiPersentase['51-75%']); ?>,
|
||||
<?php echo e($distribusiPersentase['76-99%']); ?>,
|
||||
<?php echo e($distribusiPersentase['100%']); ?>
|
||||
|
||||
],
|
||||
backgroundColor: [
|
||||
'rgba(255, 139, 148, 0.8)',
|
||||
'rgba(255, 171, 145, 0.8)',
|
||||
'rgba(255, 213, 107, 0.8)',
|
||||
'rgba(129, 198, 232, 0.8)',
|
||||
'rgba(111, 186, 157, 0.8)',
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255, 139, 148, 1)',
|
||||
'rgba(255, 171, 145, 1)',
|
||||
'rgba(255, 213, 107, 1)',
|
||||
'rgba(129, 198, 232, 1)',
|
||||
'rgba(111, 186, 157, 1)',
|
||||
],
|
||||
borderWidth: 2
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
stepSize: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Chart 3: Line Chart - Trend Progress (Load via AJAX)
|
||||
fetch('<?php echo e(route("admin.capaian.api.grafik-data")); ?>?type=trend&id_semester=<?php echo e($selectedSemester); ?>&kelas=<?php echo e($kelas); ?>')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const ctxTrend = document.getElementById('chartTrend').getContext('2d');
|
||||
const chartTrend = new Chart(ctxTrend, {
|
||||
type: 'line',
|
||||
data: data,
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
ticks: {
|
||||
callback: function(value) {
|
||||
return value + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'bottom'
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
return context.dataset.label + ': ' + context.parsed.y.toFixed(2) + '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(error => console.error('Error loading trend chart:', error));
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/capaian/dashboard.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,501 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Kartu RFID 2 Sisi - <?php echo e($santri->nama_lengkap ?? 'Preview'); ?></title>
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
size: 85.6mm 54mm;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* === SISI DEPAN === */
|
||||
.card-front {
|
||||
width: 85.6mm;
|
||||
height: 54mm;
|
||||
background: #2C3E50;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
/* Background Elements */
|
||||
.bg-circle-1 {
|
||||
position: absolute;
|
||||
top: -20mm;
|
||||
right: -20mm;
|
||||
width: 70mm;
|
||||
height: 70mm;
|
||||
background: #6FBA9D;
|
||||
border-radius: 50%;
|
||||
opacity: 0.15;
|
||||
}
|
||||
|
||||
.bg-circle-2 {
|
||||
position: absolute;
|
||||
bottom: -25mm;
|
||||
left: -15mm;
|
||||
width: 60mm;
|
||||
height: 60mm;
|
||||
background: #8FCAAE;
|
||||
border-radius: 50%;
|
||||
opacity: 0.12;
|
||||
}
|
||||
|
||||
.wave {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 45mm;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #6FBA9D 0%, #5EA98C 100%);
|
||||
clip-path: polygon(40% 0%, 100% 0%, 100% 100%, 0% 100%);
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.header {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
padding: 4mm 3.5mm;
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.logo-cell {
|
||||
display: table-cell;
|
||||
width: 12mm;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 10mm;
|
||||
height: 10mm;
|
||||
background: linear-gradient(135deg, #6FBA9D, #8FCAAE);
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 10mm;
|
||||
font-size: 16pt;
|
||||
box-shadow: 0 2mm 4mm rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.title-cell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-left: 2mm;
|
||||
}
|
||||
|
||||
.title-cell h1 {
|
||||
font-size: 11pt;
|
||||
font-weight: 900;
|
||||
color: white;
|
||||
letter-spacing: 1pt;
|
||||
text-shadow: 0 1mm 2mm rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.title-cell p {
|
||||
font-size: 6pt;
|
||||
color: #6FBA9D;
|
||||
margin-top: 0.5mm;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Content Area */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
padding: 0 3.5mm;
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.photo-col {
|
||||
display: table-cell;
|
||||
width: 22mm;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.photo-frame {
|
||||
width: 18mm;
|
||||
height: 18mm;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 2mm;
|
||||
padding: 1.5mm;
|
||||
box-shadow: 0 2mm 6mm rgba(0,0,0,0.25);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.photo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #6FBA9D, #8FCAAE);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20pt;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 5mm;
|
||||
height: 5mm;
|
||||
background: #6FBA9D;
|
||||
border-radius: 50%;
|
||||
border: 1.5mm solid white;
|
||||
text-align: center;
|
||||
line-height: 5mm;
|
||||
color: white;
|
||||
font-size: 7pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 7pt;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
text-shadow: 0 0.5mm 1mm rgba(0,0,0,0.3);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.info-col {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding: 0 2mm;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 2mm;
|
||||
padding: 2.5mm 3mm;
|
||||
box-shadow: 0 1mm 4mm rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 1.5mm;
|
||||
font-size: 6pt;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: 800;
|
||||
color: #2C3E50;
|
||||
display: inline-block;
|
||||
width: 12mm;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #34495E;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.rfid {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 5pt;
|
||||
}
|
||||
|
||||
.qr-col {
|
||||
display: table-cell;
|
||||
width: 20mm;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.qr-box {
|
||||
background: white;
|
||||
border-radius: 2mm;
|
||||
padding: 1.5mm;
|
||||
box-shadow: 0 2mm 5mm rgba(0,0,0,0.2);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.qr-img {
|
||||
width: 16mm;
|
||||
height: 16mm;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.scan {
|
||||
margin-top: 1.5mm;
|
||||
font-size: 5pt;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, #6FBA9D, #5EA98C);
|
||||
padding: 1mm 2mm;
|
||||
border-radius: 1mm;
|
||||
display: inline-block;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1.5mm;
|
||||
background: linear-gradient(90deg, #6FBA9D 0%, #5EA98C 50%, #6FBA9D 100%);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* === SISI BELAKANG === */
|
||||
.card-back {
|
||||
width: 85.6mm;
|
||||
height: 54mm;
|
||||
background: linear-gradient(135deg, #6FBA9D 0%, #5EA98C 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.back-pattern-1 {
|
||||
position: absolute;
|
||||
top: -15mm;
|
||||
left: -15mm;
|
||||
width: 50mm;
|
||||
height: 50mm;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.back-pattern-2 {
|
||||
position: absolute;
|
||||
bottom: -20mm;
|
||||
right: -20mm;
|
||||
width: 60mm;
|
||||
height: 60mm;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.back-content {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
padding: 5mm;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.back-header {
|
||||
text-align: center;
|
||||
margin-bottom: 3mm;
|
||||
}
|
||||
|
||||
.back-logo {
|
||||
width: 12mm;
|
||||
height: 12mm;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 2mm;
|
||||
text-align: center;
|
||||
line-height: 12mm;
|
||||
font-size: 20pt;
|
||||
box-shadow: 0 2mm 6mm rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.back-title {
|
||||
font-size: 10pt;
|
||||
font-weight: 900;
|
||||
color: white;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1pt;
|
||||
}
|
||||
|
||||
.back-subtitle {
|
||||
font-size: 7pt;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-top: 0.5mm;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 2mm;
|
||||
padding: 3mm;
|
||||
margin-bottom: 2mm;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 7pt;
|
||||
font-weight: 800;
|
||||
color: #2C3E50;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 2mm;
|
||||
border-bottom: 0.5mm solid #6FBA9D;
|
||||
padding-bottom: 1mm;
|
||||
}
|
||||
|
||||
.rule {
|
||||
font-size: 5.5pt;
|
||||
color: #34495E;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 1.5mm;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.rule-icon {
|
||||
color: #6FBA9D;
|
||||
margin-right: 1.5mm;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.contact {
|
||||
background: white;
|
||||
border-radius: 2mm;
|
||||
padding: 2mm 3mm;
|
||||
text-align: center;
|
||||
font-size: 5pt;
|
||||
color: #2C3E50;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
margin-bottom: 0.5mm;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.contact-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.contact-icon {
|
||||
color: #6FBA9D;
|
||||
margin-right: 1mm;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- ========== SISI DEPAN ========== -->
|
||||
<div class="card-front">
|
||||
<div class="bg-circle-1"></div>
|
||||
<div class="bg-circle-2"></div>
|
||||
<div class="wave"></div>
|
||||
|
||||
<div class="header">
|
||||
<div class="logo-cell">
|
||||
<div class="logo">🕌</div>
|
||||
</div>
|
||||
<div class="title-cell">
|
||||
<h1>PKPPS</h1>
|
||||
<p>Pesantren Riyadlul Jannah</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="photo-col">
|
||||
<div class="photo-frame">
|
||||
<div class="photo">
|
||||
<?php if(isset($santri)): ?><?php echo e(strtoupper(substr($santri->nama_lengkap, 0, 1))); ?><?php else: ?> A <?php endif; ?>
|
||||
</div>
|
||||
<div class="badge">✓</div>
|
||||
</div>
|
||||
<div class="name">
|
||||
<?php if(isset($santri)): ?><?php echo e(strtoupper(Str::limit($santri->nama_lengkap, 12, ''))); ?><?php else: ?> YOUR NAME <?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-col">
|
||||
<div class="info-box">
|
||||
<div class="info-item">
|
||||
<span class="label">ID</span>
|
||||
<span class="value">: <?php if(isset($santri)): ?><?php echo e($santri->id_santri); ?><?php else: ?> S004 <?php endif; ?></span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">Kelas</span>
|
||||
<span class="value">: <?php if(isset($santri)): ?><?php echo e($santri->kelas); ?><?php else: ?> Lambatan <?php endif; ?></span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">Status</span>
|
||||
<span class="value">: <?php if(isset($santri)): ?><?php echo e($santri->status); ?><?php else: ?> Aktif <?php endif; ?></span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">RFID</span>
|
||||
<span class="value rfid">: <?php if(isset($santri) && $santri->rfid_uid): ?><?php echo e(Str::limit($santri->rfid_uid, 14)); ?><?php else: ?> 04A3B62FD9C1 <?php endif; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="qr-col">
|
||||
<div class="qr-box">
|
||||
<?php if(isset($santri) && $santri->rfid_uid): ?>
|
||||
<img src="https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=<?php echo e(urlencode($santri->rfid_uid)); ?>" class="qr-img" alt="QR">
|
||||
<?php else: ?>
|
||||
<img src="https://chart.googleapis.com/chart?cht=qr&chs=200x200&chl=04A3B62FD9C1" class="qr-img" alt="QR">
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="scan">SCAN ME</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer"></div>
|
||||
</div>
|
||||
|
||||
<!-- ========== SISI BELAKANG ========== -->
|
||||
<div class="card-back">
|
||||
<div class="back-pattern-1"></div>
|
||||
<div class="back-pattern-2"></div>
|
||||
|
||||
<div class="back-content">
|
||||
<div class="back-header">
|
||||
<div class="back-logo">🕌</div>
|
||||
<div class="back-title">PKPPS</div>
|
||||
<div class="back-subtitle">Pesantren Riyadlul Jannah</div>
|
||||
</div>
|
||||
|
||||
<div class="info-section">
|
||||
<div class="section-title">📋 Ketentuan Kartu</div>
|
||||
<div class="rule">
|
||||
<span class="rule-icon">✓</span>
|
||||
<span>Kartu ini adalah identitas resmi santri PKPPS</span>
|
||||
</div>
|
||||
<div class="rule">
|
||||
<span class="rule-icon">✓</span>
|
||||
<span>Wajib dibawa setiap saat di lingkungan pesantren</span>
|
||||
</div>
|
||||
<div class="rule">
|
||||
<span class="rule-icon">✓</span>
|
||||
<span>Digunakan untuk absensi kegiatan dan akses fasilitas</span>
|
||||
</div>
|
||||
<div class="rule">
|
||||
<span class="rule-icon">✓</span>
|
||||
<span>Jika hilang segera lapor ke bagian administrasi</span>
|
||||
</div>
|
||||
<div class="rule">
|
||||
<span class="rule-icon">✓</span>
|
||||
<span>Harap dijaga dan tidak dipinjamkan</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="contact">
|
||||
<div class="contact-item">
|
||||
<span class="contact-icon">📍</span> Jl. Pesantren No. 123, Yogyakarta
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<span class="contact-icon">📞</span> (0274) 123-4567
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<span class="contact-icon">📧</span> admin@pkpps.ac.id
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kegiatan/kartu/cetak.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Pembayaran SPP'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-money-bill-wave"></i> Pembayaran SPP</h2>
|
||||
</div>
|
||||
|
||||
<?php if(session('success')): ?>
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-check-circle"></i> <?php echo e(session('success')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(session('error')): ?>
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php echo e(session('error')); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content-box">
|
||||
<!-- Header Actions -->
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 15px;">
|
||||
<!-- Search & Filter Form -->
|
||||
<form method="GET" action="<?php echo e(route('admin.pembayaran-spp.index')); ?>" style="display: flex; gap: 10px; flex-wrap: wrap; flex: 1;">
|
||||
<input type="text"
|
||||
name="search"
|
||||
class="form-control"
|
||||
placeholder="Cari santri atau ID..."
|
||||
value="<?php echo e(request('search')); ?>"
|
||||
style="max-width: 250px;">
|
||||
|
||||
<select name="status" class="form-control" style="max-width: 180px;">
|
||||
<option value="">Semua Status</option>
|
||||
<option value="Lunas" <?php echo e(request('status') === 'Lunas' ? 'selected' : ''); ?>>Lunas</option>
|
||||
<option value="Belum Lunas" <?php echo e(request('status') === 'Belum Lunas' ? 'selected' : ''); ?>>Belum Lunas</option>
|
||||
<option value="Telat" <?php echo e(request('status') === 'Telat' ? 'selected' : ''); ?>>Telat</option>
|
||||
</select>
|
||||
|
||||
<select name="bulan" class="form-control" style="max-width: 150px;">
|
||||
<option value="">Semua Bulan</option>
|
||||
<?php for($i = 1; $i <= 12; $i++): ?>
|
||||
<option value="<?php echo e($i); ?>" <?php echo e(request('bulan') == $i ? 'selected' : ''); ?>>
|
||||
<?php echo e(DateTime::createFromFormat('!m', $i)->format('F')); ?>
|
||||
|
||||
</option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
|
||||
<select name="tahun" class="form-control" style="max-width: 120px;">
|
||||
<option value="">Semua Tahun</option>
|
||||
<?php $__currentLoopData = $tahunList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $tahun): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($tahun); ?>" <?php echo e(request('tahun') == $tahun ? 'selected' : ''); ?>>
|
||||
<?php echo e($tahun); ?>
|
||||
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-search"></i> Cari
|
||||
</button>
|
||||
|
||||
<?php if(request()->hasAny(['search', 'status', 'bulan', 'tahun'])): ?>
|
||||
<a href="<?php echo e(route('admin.pembayaran-spp.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-times"></i> Reset
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div style="display: flex; gap: 10px;">
|
||||
<a href="<?php echo e(route('admin.pembayaran-spp.generate')); ?>" class="btn btn-warning btn-sm hover-shadow">
|
||||
<i class="fas fa-cogs"></i> Generate SPP
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.pembayaran-spp.create')); ?>" class="btn btn-success btn-sm hover-shadow">
|
||||
<i class="fas fa-plus-circle"></i> Tambah Data
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>ID Pembayaran</th>
|
||||
<th>Santri</th>
|
||||
<th>Periode</th>
|
||||
<th>Nominal</th>
|
||||
<th>Batas Bayar</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__empty_1 = true; $__currentLoopData = $pembayaranSpp; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $spp): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); $__empty_1 = false; ?>
|
||||
<tr>
|
||||
<td><?php echo e($pembayaranSpp->firstItem() + $index); ?></td>
|
||||
<td><strong><?php echo e($spp->id_pembayaran); ?></strong></td>
|
||||
<td>
|
||||
<strong><?php echo e($spp->santri->nama_lengkap); ?></strong><br>
|
||||
<small class="text-muted"><?php echo e($spp->santri->id_santri); ?> - <?php echo e($spp->santri->kelas); ?></small>
|
||||
</td>
|
||||
<td><?php echo e($spp->periode_lengkap); ?></td>
|
||||
<td><strong><?php echo e($spp->nominal_format); ?></strong></td>
|
||||
<td>
|
||||
<?php echo e($spp->batas_bayar->format('d/m/Y')); ?>
|
||||
|
||||
<?php if($spp->isTelat()): ?>
|
||||
<br><small class="text-muted" style="color: #FF8B94 !important;">
|
||||
<i class="fas fa-exclamation-triangle"></i> Telat
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo $spp->status_badge; ?></td>
|
||||
<td class="text-center">
|
||||
<a href="<?php echo e(route('admin.pembayaran-spp.show', $spp->id)); ?>"
|
||||
class="btn btn-sm btn-primary"
|
||||
title="Detail">
|
||||
<i class="fas fa-eye"></i>
|
||||
</a>
|
||||
<a href="<?php echo e(route('admin.pembayaran-spp.edit', $spp->id)); ?>"
|
||||
class="btn btn-sm btn-warning"
|
||||
title="Edit">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<form action="<?php echo e(route('admin.pembayaran-spp.destroy', $spp->id)); ?>"
|
||||
method="POST"
|
||||
style="display: inline-block;"
|
||||
onsubmit="return confirm('Yakin ingin menghapus data ini?')">
|
||||
<?php echo csrf_field(); ?>
|
||||
<?php echo method_field('DELETE'); ?>
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="Hapus">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); if ($__empty_1): ?>
|
||||
<tr>
|
||||
<td colspan="8" class="text-center" style="padding: 40px;">
|
||||
<i class="fas fa-inbox" style="font-size: 3rem; color: #ccc; display: block; margin-bottom: 15px;"></i>
|
||||
<p style="color: #999;">Tidak ada data pembayaran SPP.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<?php if($pembayaranSpp->hasPages()): ?>
|
||||
<div style="margin-top: 20px;">
|
||||
<?php echo e($pembayaranSpp->links()); ?>
|
||||
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/pembayaran-spp/index.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,421 +0,0 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Tambah Berita Baru'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-plus-circle"></i> Tambah Berita Baru</h2>
|
||||
</div>
|
||||
|
||||
<!-- Alert Errors -->
|
||||
<?php if($errors->any()): ?>
|
||||
<div class="alert alert-danger">
|
||||
<strong><i class="fas fa-exclamation-circle"></i> Terdapat kesalahan:</strong>
|
||||
<ul style="margin: 10px 0 0 20px;">
|
||||
<?php $__currentLoopData = $errors->all(); $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $error): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<li><?php echo e($error); ?></li>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="content-box">
|
||||
<form action="<?php echo e(route('admin.berita.store')); ?>" method="POST" enctype="multipart/form-data">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<!-- Judul Berita -->
|
||||
<div class="form-group">
|
||||
<label for="judul">
|
||||
<i class="fas fa-heading form-icon"></i>
|
||||
Judul Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
id="judul"
|
||||
name="judul"
|
||||
class="form-control <?php $__errorArgs = ['judul'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('judul')); ?>"
|
||||
placeholder="Masukkan judul berita..."
|
||||
required>
|
||||
<?php $__errorArgs = ['judul'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<!-- Konten Berita -->
|
||||
<div class="form-group">
|
||||
<label for="konten">
|
||||
<i class="fas fa-align-left form-icon"></i>
|
||||
Konten Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<textarea id="konten"
|
||||
name="konten"
|
||||
class="form-control <?php $__errorArgs = ['konten'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
rows="10"
|
||||
placeholder="Tulis konten berita di sini..."
|
||||
required><?php echo e(old('konten')); ?></textarea>
|
||||
<?php $__errorArgs = ['konten'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<!-- Penulis & Gambar -->
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div class="form-group">
|
||||
<label for="penulis">
|
||||
<i class="fas fa-user-edit form-icon"></i>
|
||||
Penulis <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
id="penulis"
|
||||
name="penulis"
|
||||
class="form-control <?php $__errorArgs = ['penulis'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('penulis')); ?>"
|
||||
placeholder="Nama penulis berita"
|
||||
required>
|
||||
<?php $__errorArgs = ['penulis'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="gambar">
|
||||
<i class="fas fa-image form-icon"></i>
|
||||
Gambar Berita (Opsional)
|
||||
</label>
|
||||
<input type="file"
|
||||
id="gambar"
|
||||
name="gambar"
|
||||
class="form-control <?php $__errorArgs = ['gambar'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
accept="image/*">
|
||||
<small class="form-text">Format: JPG, PNG, GIF. Maksimal 2MB.</small>
|
||||
<?php $__errorArgs = ['gambar'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Target & Status -->
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div class="form-group">
|
||||
<label for="target_berita">
|
||||
<i class="fas fa-bullseye form-icon"></i>
|
||||
Target Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<select id="target_berita"
|
||||
name="target_berita"
|
||||
class="form-control <?php $__errorArgs = ['target_berita'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
required>
|
||||
<option value="">-- Pilih Target --</option>
|
||||
<option value="semua" <?php echo e(old('target_berita') == 'semua' ? 'selected' : ''); ?>>
|
||||
Semua Santri
|
||||
</option>
|
||||
<option value="kelas_tertentu" <?php echo e(old('target_berita') == 'kelas_tertentu' ? 'selected' : ''); ?>>
|
||||
Kelas Tertentu
|
||||
</option>
|
||||
<option value="santri_tertentu" <?php echo e(old('target_berita') == 'santri_tertentu' ? 'selected' : ''); ?>>
|
||||
Santri Tertentu
|
||||
</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['target_berita'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="status">
|
||||
<i class="fas fa-toggle-on form-icon"></i>
|
||||
Status Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<select id="status"
|
||||
name="status"
|
||||
class="form-control <?php $__errorArgs = ['status'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
required>
|
||||
<option value="">-- Pilih Status --</option>
|
||||
<option value="draft" <?php echo e(old('status') == 'draft' ? 'selected' : ''); ?>>
|
||||
Draft (Belum Dipublikasi)
|
||||
</option>
|
||||
<option value="published" <?php echo e(old('status') == 'published' ? 'selected' : ''); ?>>
|
||||
Published (Dipublikasi)
|
||||
</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['status'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<span class="invalid-feedback"><?php echo e($message); ?></span>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section: Pilih Kelas Tertentu -->
|
||||
<div id="kelas-section" class="form-group" style="display: none;">
|
||||
<label>
|
||||
<i class="fas fa-graduation-cap form-icon"></i>
|
||||
Pilih Kelas yang Akan Menerima Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
<div style="border: 2px solid var(--primary-light); border-radius: var(--border-radius-sm); padding: 20px; background-color: var(--primary-light);">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px;">
|
||||
<?php $__currentLoopData = $kelasOptions; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $kelas): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div style="background: white; padding: 12px; border-radius: var(--border-radius-sm); box-shadow: var(--shadow-sm);">
|
||||
<label style="display: flex; align-items: center; margin: 0; cursor: pointer;">
|
||||
<input type="checkbox"
|
||||
id="kelas_<?php echo e($kelas); ?>"
|
||||
name="target_kelas[]"
|
||||
value="<?php echo e($kelas); ?>"
|
||||
class="kelas-checkbox"
|
||||
style="margin-right: 10px; width: 18px; height: 18px;"
|
||||
<?php echo e(in_array($kelas, old('target_kelas', [])) ? 'checked' : ''); ?>>
|
||||
<span style="font-weight: 600; color: var(--text-color);">
|
||||
Kelas <?php echo e($kelas); ?>
|
||||
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<small class="form-text">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span id="selected-kelas-count">0</span> kelas dipilih dari <?php echo e(count($kelasOptions)); ?> total kelas.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Section: Pilih Santri Tertentu -->
|
||||
<div id="santri-section" class="form-group" style="display: none;">
|
||||
<label>
|
||||
<i class="fas fa-users form-icon"></i>
|
||||
Pilih Santri yang Akan Menerima Berita <span style="color: var(--danger-color);">*</span>
|
||||
</label>
|
||||
|
||||
<!-- Select All -->
|
||||
<div style="background: var(--primary-light); padding: 12px; border-radius: var(--border-radius-sm); margin-bottom: 10px;">
|
||||
<label style="display: flex; align-items: center; margin: 0; cursor: pointer; font-weight: 600;">
|
||||
<input type="checkbox"
|
||||
id="select-all"
|
||||
style="margin-right: 10px; width: 20px; height: 20px;">
|
||||
<span style="color: var(--primary-dark);">
|
||||
<i class="fas fa-check-double"></i> Pilih Semua Santri
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- List Santri -->
|
||||
<div style="border: 2px solid var(--primary-light); border-radius: var(--border-radius-sm); padding: 15px; max-height: 400px; overflow-y: auto; background-color: #FAFAFA;">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px;">
|
||||
<?php $__currentLoopData = $santri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $s): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<div style="background: white; padding: 12px; border-radius: var(--border-radius-sm); box-shadow: var(--shadow-sm); transition: all 0.2s ease;">
|
||||
<label style="display: flex; align-items: center; gap: 10px; margin: 0; cursor: pointer;">
|
||||
<input type="checkbox"
|
||||
id="santri_<?php echo e($s->id_santri); ?>"
|
||||
name="santri_tertentu[]"
|
||||
value="<?php echo e($s->id_santri); ?>"
|
||||
class="santri-checkbox"
|
||||
style="width: 18px; height: 18px; flex-shrink: 0;"
|
||||
<?php echo e(in_array($s->id_santri, old('santri_tertentu', [])) ? 'checked' : ''); ?>>
|
||||
|
||||
<!-- Hanya tampilkan initial, tanpa foto -->
|
||||
<div style="width: 40px; height: 40px; border-radius: 50%; background: var(--primary-color); display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; flex-shrink: 0;">
|
||||
<?php echo e(strtoupper(substr($s->nama_lengkap, 0, 1))); ?>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="flex-grow: 1; min-width: 0;">
|
||||
<div style="font-weight: 600; color: var(--primary-color); font-size: 0.85em;">
|
||||
<?php echo e($s->id_santri); ?>
|
||||
|
||||
</div>
|
||||
<div style="font-weight: 500; color: var(--text-color); font-size: 0.9em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
|
||||
<?php echo e($s->nama_lengkap); ?>
|
||||
|
||||
</div>
|
||||
<div style="font-size: 0.8em; color: var(--text-light);">
|
||||
<?php echo e($s->kelas); ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</div>
|
||||
</div>
|
||||
<small class="form-text">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span id="selected-count">0</span> santri dipilih dari <?php echo e($santri->count()); ?> total santri aktif.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Submit Buttons -->
|
||||
<div style="display: flex; gap: 10px; margin-top: 30px; padding-top: 20px; border-top: 2px solid var(--primary-light);">
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="fas fa-save"></i> Simpan Berita
|
||||
</button>
|
||||
<a href="<?php echo e(route('admin.berita.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i> Batal
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const targetBerita = document.getElementById('target_berita');
|
||||
const santriSection = document.getElementById('santri-section');
|
||||
const kelasSection = document.getElementById('kelas-section');
|
||||
const selectAll = document.getElementById('select-all');
|
||||
const santriCheckboxes = document.querySelectorAll('.santri-checkbox');
|
||||
const kelasCheckboxes = document.querySelectorAll('.kelas-checkbox');
|
||||
const selectedCount = document.getElementById('selected-count');
|
||||
const selectedKelasCount = document.getElementById('selected-kelas-count');
|
||||
|
||||
// Toggle sections berdasarkan target berita
|
||||
targetBerita.addEventListener('change', function() {
|
||||
santriSection.style.display = 'none';
|
||||
kelasSection.style.display = 'none';
|
||||
|
||||
if (this.value === 'santri_tertentu') {
|
||||
santriSection.style.display = 'block';
|
||||
} else if (this.value === 'kelas_tertentu') {
|
||||
kelasSection.style.display = 'block';
|
||||
} else {
|
||||
// Reset checkboxes
|
||||
if (selectAll) selectAll.checked = false;
|
||||
santriCheckboxes.forEach(cb => cb.checked = false);
|
||||
kelasCheckboxes.forEach(cb => cb.checked = false);
|
||||
updateSelectedCount();
|
||||
updateSelectedKelasCount();
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger on page load jika ada old value
|
||||
if (targetBerita.value === 'santri_tertentu') {
|
||||
santriSection.style.display = 'block';
|
||||
} else if (targetBerita.value === 'kelas_tertentu') {
|
||||
kelasSection.style.display = 'block';
|
||||
}
|
||||
|
||||
// Select All functionality untuk santri
|
||||
if (selectAll) {
|
||||
selectAll.addEventListener('change', function() {
|
||||
santriCheckboxes.forEach(checkbox => {
|
||||
checkbox.checked = this.checked;
|
||||
});
|
||||
updateSelectedCount();
|
||||
});
|
||||
}
|
||||
|
||||
// Update select all ketika checkbox santri individual berubah
|
||||
santriCheckboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
const checkedCount = document.querySelectorAll('.santri-checkbox:checked').length;
|
||||
if (selectAll) {
|
||||
selectAll.checked = checkedCount === santriCheckboxes.length;
|
||||
selectAll.indeterminate = checkedCount > 0 && checkedCount < santriCheckboxes.length;
|
||||
}
|
||||
updateSelectedCount();
|
||||
});
|
||||
});
|
||||
|
||||
// Update counter untuk kelas
|
||||
kelasCheckboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', updateSelectedKelasCount);
|
||||
});
|
||||
|
||||
// Functions untuk update counter
|
||||
function updateSelectedCount() {
|
||||
const checkedCount = document.querySelectorAll('.santri-checkbox:checked').length;
|
||||
if (selectedCount) selectedCount.textContent = checkedCount;
|
||||
}
|
||||
|
||||
function updateSelectedKelasCount() {
|
||||
const checkedCount = document.querySelectorAll('.kelas-checkbox:checked').length;
|
||||
if (selectedKelasCount) selectedKelasCount.textContent = checkedCount;
|
||||
}
|
||||
|
||||
// Initial count
|
||||
updateSelectedCount();
|
||||
updateSelectedKelasCount();
|
||||
});
|
||||
</script>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/berita/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
|
||||
|
||||
<?php $__env->startSection('title', 'Tambah Data Kesehatan Santri'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-plus-circle"></i> Tambah Data Kesehatan Santri</h2>
|
||||
</div>
|
||||
|
||||
<!-- Content Box -->
|
||||
<div class="content-box">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||||
<h3 style="margin: 0; color: var(--primary-color);">
|
||||
<i class="fas fa-file-medical"></i> Form Data Kesehatan
|
||||
</h3>
|
||||
<a href="<?php echo e(route('admin.kesehatan-santri.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Kembali
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form action="<?php echo e(route('admin.kesehatan-santri.store')); ?>" method="POST">
|
||||
<?php echo csrf_field(); ?>
|
||||
|
||||
<!-- Pilih Santri -->
|
||||
<div class="form-group">
|
||||
<label for="id_santri"><i class="fas fa-user form-icon"></i>Santri *</label>
|
||||
<select name="id_santri" id="id_santri" class="form-control <?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Santri --</option>
|
||||
<?php $__currentLoopData = $santri; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $s): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<option value="<?php echo e($s->id_santri); ?>" <?php echo e(old('id_santri') == $s->id_santri ? 'selected' : ''); ?>>
|
||||
<?php echo e($s->id_santri); ?> - <?php echo e($s->nama_lengkap); ?> (<?php echo e($s->kelas); ?>)
|
||||
</option>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</select>
|
||||
<?php $__errorArgs = ['id_santri'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<!-- Tanggal Masuk -->
|
||||
<div class="form-group">
|
||||
<label for="tanggal_masuk"><i class="fas fa-calendar-plus form-icon"></i>Tanggal Masuk UKP *</label>
|
||||
<input type="date"
|
||||
name="tanggal_masuk"
|
||||
id="tanggal_masuk"
|
||||
class="form-control <?php $__errorArgs = ['tanggal_masuk'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('tanggal_masuk', date('Y-m-d'))); ?>"
|
||||
max="<?php echo e(date('Y-m-d')); ?>"
|
||||
required>
|
||||
<?php $__errorArgs = ['tanggal_masuk'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
|
||||
<!-- Status -->
|
||||
<div class="form-group">
|
||||
<label for="status"><i class="fas fa-info-circle form-icon"></i>Status *</label>
|
||||
<select name="status" id="status" class="form-control <?php $__errorArgs = ['status'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>" required>
|
||||
<option value="">-- Pilih Status --</option>
|
||||
<option value="dirawat" <?php echo e(old('status') == 'dirawat' ? 'selected' : ''); ?>>Dirawat</option>
|
||||
<option value="sembuh" <?php echo e(old('status') == 'sembuh' ? 'selected' : ''); ?>>Sembuh</option>
|
||||
<option value="izin" <?php echo e(old('status') == 'izin' ? 'selected' : ''); ?>>Izin Pulang</option>
|
||||
</select>
|
||||
<?php $__errorArgs = ['status'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tanggal Keluar (Hidden by default) -->
|
||||
<div id="tanggal_keluar_group" class="form-group" style="display: none;">
|
||||
<label for="tanggal_keluar"><i class="fas fa-calendar-check form-icon"></i>Tanggal Keluar UKP</label>
|
||||
<input type="date"
|
||||
name="tanggal_keluar"
|
||||
id="tanggal_keluar"
|
||||
class="form-control <?php $__errorArgs = ['tanggal_keluar'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
value="<?php echo e(old('tanggal_keluar')); ?>"
|
||||
max="<?php echo e(date('Y-m-d')); ?>">
|
||||
<?php $__errorArgs = ['tanggal_keluar'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">
|
||||
<i class="fas fa-info-circle"></i> Kosongkan jika santri masih dirawat
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<!-- Keluhan -->
|
||||
<div class="form-group">
|
||||
<label for="keluhan"><i class="fas fa-notes-medical form-icon"></i>Keluhan *</label>
|
||||
<textarea name="keluhan"
|
||||
id="keluhan"
|
||||
rows="4"
|
||||
class="form-control <?php $__errorArgs = ['keluhan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
placeholder="Tuliskan keluhan atau gejala yang dialami santri..."
|
||||
required><?php echo e(old('keluhan')); ?></textarea>
|
||||
<?php $__errorArgs = ['keluhan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">Maksimal 1000 karakter</small>
|
||||
</div>
|
||||
|
||||
<!-- Catatan -->
|
||||
<div class="form-group">
|
||||
<label for="catatan"><i class="fas fa-clipboard form-icon"></i>Catatan Petugas</label>
|
||||
<textarea name="catatan"
|
||||
id="catatan"
|
||||
rows="3"
|
||||
class="form-control <?php $__errorArgs = ['catatan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?> is-invalid <?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>"
|
||||
placeholder="Catatan tambahan dari petugas kesehatan..."><?php echo e(old('catatan')); ?></textarea>
|
||||
<?php $__errorArgs = ['catatan'];
|
||||
$__bag = $errors->getBag($__errorArgs[1] ?? 'default');
|
||||
if ($__bag->has($__errorArgs[0])) :
|
||||
if (isset($message)) { $__messageOriginal = $message; }
|
||||
$message = $__bag->first($__errorArgs[0]); ?>
|
||||
<div class="invalid-feedback"><?php echo e($message); ?></div>
|
||||
<?php unset($message);
|
||||
if (isset($__messageOriginal)) { $message = $__messageOriginal; }
|
||||
endif;
|
||||
unset($__errorArgs, $__bag); ?>
|
||||
<small class="form-text">Maksimal 1000 karakter (opsional)</small>
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div style="display: flex; gap: 10px; justify-content: flex-end; margin-top: 30px;">
|
||||
<a href="<?php echo e(route('admin.kesehatan-santri.index')); ?>" class="btn btn-secondary">
|
||||
<i class="fas fa-times"></i> Batal
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> Simpan Data
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const statusSelect = document.getElementById('status');
|
||||
const tanggalKeluarGroup = document.getElementById('tanggal_keluar_group');
|
||||
const tanggalKeluarInput = document.getElementById('tanggal_keluar');
|
||||
const tanggalMasukInput = document.getElementById('tanggal_masuk');
|
||||
|
||||
// Function to toggle tanggal keluar visibility
|
||||
function toggleTanggalKeluar() {
|
||||
if (statusSelect.value === 'dirawat') {
|
||||
tanggalKeluarGroup.style.display = 'none';
|
||||
tanggalKeluarInput.value = '';
|
||||
tanggalKeluarInput.removeAttribute('required');
|
||||
} else {
|
||||
tanggalKeluarGroup.style.display = 'block';
|
||||
if (statusSelect.value === 'sembuh' || statusSelect.value === 'izin') {
|
||||
tanggalKeluarInput.setAttribute('required', 'required');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set minimum date for tanggal_keluar based on tanggal_masuk
|
||||
function setMinTanggalKeluar() {
|
||||
if (tanggalMasukInput.value) {
|
||||
tanggalKeluarInput.min = tanggalMasukInput.value;
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
statusSelect.addEventListener('change', toggleTanggalKeluar);
|
||||
tanggalMasukInput.addEventListener('change', setMinTanggalKeluar);
|
||||
|
||||
// Initialize on page load
|
||||
toggleTanggalKeluar();
|
||||
setMinTanggalKeluar();
|
||||
|
||||
// Character counter
|
||||
function setupCharacterCounter(textareaId, maxLength) {
|
||||
const textarea = document.getElementById(textareaId);
|
||||
const counter = document.createElement('div');
|
||||
counter.style.cssText = 'text-align: right; font-size: 0.85em; color: #7F8C8D; margin-top: 5px;';
|
||||
|
||||
function updateCounter() {
|
||||
const remaining = maxLength - textarea.value.length;
|
||||
counter.textContent = `${textarea.value.length}/${maxLength} karakter`;
|
||||
counter.style.color = remaining < 50 ? '#E74C3C' : '#7F8C8D';
|
||||
}
|
||||
|
||||
textarea.addEventListener('input', updateCounter);
|
||||
|
||||
// Insert counter after the last sibling (after form-text if exists)
|
||||
const lastSibling = textarea.parentNode.lastElementChild;
|
||||
if (lastSibling.classList && lastSibling.classList.contains('form-text')) {
|
||||
lastSibling.parentNode.appendChild(counter);
|
||||
} else {
|
||||
textarea.parentNode.appendChild(counter);
|
||||
}
|
||||
|
||||
updateCounter();
|
||||
}
|
||||
|
||||
setupCharacterCounter('keluhan', 1000);
|
||||
setupCharacterCounter('catatan', 1000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/admin/kesehatan-santri/create.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
|
||||
|
||||
|
||||
<?php $__env->startSection('title', 'Daftar Kategori Pelanggaran'); ?>
|
||||
|
||||
<?php $__env->startSection('content'); ?>
|
||||
<div class="page-header">
|
||||
<h2><i class="fas fa-list-ul"></i> Daftar Kategori Pelanggaran & Poin</h2>
|
||||
</div>
|
||||
|
||||
<div class="content-box">
|
||||
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
|
||||
<p class="text-muted">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Berikut adalah daftar kategori pelanggaran beserta poin yang berlaku di pondok.
|
||||
</p>
|
||||
<a href="<?php echo e(route('santri.pelanggaran.index')); ?>" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-arrow-left"></i> Kembali ke Riwayat
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if($kategoriList->count() > 0): ?>
|
||||
<div style="overflow-x: auto;">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 8%;">No</th>
|
||||
<th style="width: 15%;">Kode</th>
|
||||
<th style="width: 57%;">Jenis Pelanggaran</th>
|
||||
<th style="width: 20%; text-align: center;">Poin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $__currentLoopData = $kategoriList; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $index => $kategori): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
|
||||
<tr>
|
||||
<td><?php echo e($index + 1); ?></td>
|
||||
<td><strong><?php echo e($kategori->id_kategori); ?></strong></td>
|
||||
<td><?php echo e($kategori->nama_pelanggaran); ?></td>
|
||||
<td class="text-center">
|
||||
<?php if($kategori->poin <= 5): ?>
|
||||
<span class="badge badge-warning badge-lg">
|
||||
<i class="fas fa-star"></i> <?php echo e($kategori->poin); ?> Poin
|
||||
</span>
|
||||
<?php elseif($kategori->poin <= 15): ?>
|
||||
<span class="badge badge-danger badge-lg">
|
||||
<i class="fas fa-star"></i> <?php echo e($kategori->poin); ?> Poin
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<span class="badge badge-danger badge-lg" style="background: linear-gradient(135deg, #dc3545 0%, #a71d2a 100%);">
|
||||
<i class="fas fa-star"></i> <?php echo e($kategori->poin); ?> Poin
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-list"></i>
|
||||
<h3>Belum Ada Kategori</h3>
|
||||
<p>Daftar kategori pelanggaran belum tersedia.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php $__env->stopSection(); ?>
|
||||
<?php echo $__env->make('layouts.app', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH C:\xampp\htdocs\TugasAkhir\sim-pkpps\resources\views/santri/pelanggaran/kategori.blade.php ENDPATH**/ ?>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.build/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
.swiftpm/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: android
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: ios
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: linux
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: macos
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: web
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
- platform: windows
|
||||
create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# sim_mobile
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at https://dart.dev/lints.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
.cxx/
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/to/reference-keystore
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
plugins {
|
||||
id("com.android.application")
|
||||
id("kotlin-android")
|
||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||
id("dev.flutter.flutter-gradle-plugin")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.sim_mobile"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_11.toString()
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "com.example.sim_mobile"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = flutter.minSdkVersion
|
||||
targetSdk = flutter.targetSdkVersion
|
||||
versionCode = flutter.versionCode
|
||||
versionName = flutter.versionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source = "../.."
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application
|
||||
android:label="sim_mobile"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.example.sim_mobile
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity : FlutterActivity()
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 544 B |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue