TIF_NGANJUK_E41220778/app/Http/Controllers/DashboardController.php

173 lines
6.7 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Announcement;
use App\Models\Book;
use App\Models\Loan;
use App\Models\Recommendation;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class DashboardController extends Controller
{
public function index()
{
$user = Auth::user();
// Fetch active loans for the user
$loans = Loan::with('book')
->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;
}
}