where('user_id', $user->id) ->whereIn('status', ['Dipinjam', 'Terlambat']) ->get(); $bukuPinjamOffline = $loans->map(function ($loan) { $dueAt = Carbon::parse($loan->due_at); $sisaHari = (int) now()->diffInDays($dueAt, false); return [ 'id' => $loan->book->id, 'judul' => $loan->book->judul, 'penulis' => $loan->book->penulis, 'sisa_hari' => $sisaHari, 'cover' => $loan->book->cover, ]; }); // Check if user has overdue books $isTelat = $bukuPinjamOffline->contains(fn($b) => $b['sisa_hari'] < 0); if ($isTelat && $user->role === 'siswa') { $user->update(['is_banned' => true]); } // Stats calculation $stats = [ ['label' => 'Buku yang dipinjam', 'value' => $loans->count(), 'icon' => 'bi-book-half', 'color' => 'primary'], ['label' => 'Tenggat Waktu', 'value' => $bukuPinjamOffline->where('sisa_hari', '<=', 3)->where('sisa_hari', '>=', 0)->count(), 'icon' => 'bi-clock-history', 'color' => 'danger'], ['label' => 'Buku dikembalikan', 'value' => Loan::where('user_id', $user->id)->where('status', 'Dikembalikan')->count(), 'icon' => 'bi-check-circle', 'color' => 'success'], ['label' => 'History Baca', 'value' => Loan::where('user_id', $user->id)->count(), 'icon' => 'bi-hourglass-split', 'color' => 'warning'], ]; $pengumuman = Announcement::latest()->take(5)->get(); // Placeholder for pemberitahuan (system notifications) $pemberitahuan = collect([ ['type' => 'info', 'icon' => 'bi-bell-fill', 'title' => 'Selamat Datang', 'content' => 'Selamat datang di perpustakaan digital SMKN 1.', 'badge' => 'Baru'] ]); // Dynamic reading progress based on returned vs total books $totalUserLoans = Loan::where('user_id', $user->id)->count(); $returnedLoans = Loan::where('user_id', $user->id)->where('status', 'Dikembalikan')->count(); $progressSelesai = $totalUserLoans > 0 ? round(($returnedLoans / $totalUserLoans) * 100) : 0; $progressMembaca = ['selesai' => $progressSelesai, 'sisa' => 100 - $progressSelesai]; // Dynamic monthly stats for the last 7 months $labels = []; $data = []; for ($i = 6; $i >= 0; $i--) { $month = Carbon::now()->subMonths($i); $labels[] = $month->translatedFormat('M'); $data[] = Loan::where('user_id', $user->id) ->whereMonth('borrowed_at', $month->month) ->whereYear('borrowed_at', $month->year) ->count(); } $statistikBulanan = [ 'labels' => $labels, 'data' => $data, ]; // Online books (books with 'online' in tipe_akses) $bacaBukuOnline = $loans->filter(function ($loan) { return in_array('online', $loan->book->tipe_akses ?? []); })->map(fn($loan) => [ 'judul' => $loan->book->judul, 'penulis' => $loan->book->penulis, 'progress' => 0, // Placeholder 'cover' => $loan->book->cover, ]); $recommendations = Recommendation::all(); $rekomendasiPembelajaran = $recommendations->map(function ($item) { $videoId = $this->extractYouTubeId($item->youtube_link); return [ 'id' => $item->id, 'judul' => $item->judul, 'kategori' => $item->kategori, 'thumbnail' => $videoId ? "https://img.youtube.com/vi/{$videoId}/hqdefault.jpg" : 'https://via.placeholder.com/150?text=No+Preview', 'youtube_link' => $item->youtube_link, 'deskripsi' => $item->deskripsi, ]; }); // Dynamic notifications based on loans $personalNotif = collect(); foreach ($bukuPinjamOffline as $buku) { if ($buku['sisa_hari'] < 0) { $hariTelat = abs($buku['sisa_hari']); $denda = $hariTelat * 1000; $personalNotif->push([ 'icon' => 'bi-exclamation-octagon-fill', 'color' => 'danger', 'title' => 'TERLAMBAT: ' . $buku['judul'], 'content' => "Telat {$hariTelat} hari. Denda: Rp " . number_format($denda, 0, ',', '.'), 'time' => 'Sekarang', 'read' => false, 'type' => 'denda_active', ]); } elseif ($buku['sisa_hari'] <= 3) { $personalNotif->push([ 'icon' => 'bi-exclamation-triangle-fill', 'color' => 'warning', 'title' => 'Jatuh Tempo: ' . $buku['judul'], 'content' => "Sisa waktu tinggal " . $buku['sisa_hari'] . " hari lagi.", 'time' => 'Segera', 'read' => false, 'type' => 'warning_jatuh_tempo', ]); } } $personalNotif->push([ 'icon' => 'bi-info-circle-fill', 'color' => 'primary', 'title' => 'Selamat Datang!', 'content' => 'Jelajahi koleksi buku terbaru kami.', 'time' => 'Baru saja', 'read' => true, 'type' => 'info', ]); $dendaAlert = $personalNotif->where('type', 'denda_active'); $hour = date('H'); $greeting = "Selamat Pagi"; if ($hour >= 12 && $hour < 15) $greeting = "Selamat Siang"; elseif ($hour >= 15 && $hour < 18) $greeting = "Selamat Sore"; elseif ($hour >= 18) $greeting = "Selamat Malam"; return view('dashboard', compact( 'user', 'stats', 'pengumuman', 'pemberitahuan', 'dendaAlert', 'progressMembaca', 'statistikBulanan', 'bukuPinjamOffline', 'bacaBukuOnline', 'greeting', 'rekomendasiPembelajaran' ))->with('notifikasi', $personalNotif); } private function extractYouTubeId(string $url): ?string { preg_match('/(v=|vi=|youtu.be\/|embed\/|\/v\/|\?v=|\&v=)(.+?)\b/i', $url, $matches); return $matches[2] ?? null; } }