Files
spota-dev/rebuild/app/Http/Controllers/Dashboard/DosenDashboardController.php
Power BI Dev dab8ea396b Deploy Laravel rebuild via Coolify
Point Docker and Coolify compose to the Laravel rebuild app so mahasiswa, dosen, and admin flows are served from the new Laravel public entrypoint.
2026-05-03 18:50:29 +07:00

275 lines
12 KiB
PHP

<?php
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Support\DosenNavigation;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
class DosenDashboardController extends Controller
{
public function __invoke(Request $request): View
{
$auth = $request->session()->get('legacy_auth');
abort_unless(($auth['role'] ?? null) === 'dosen', 403);
$user = $auth['user'];
$cachePrefix = 'rebuild:dosen:dashboard:'.$user['prodi'].':'.$user['id'];
$today = now();
$startOfMonth = $today->copy()->startOfMonth();
$endOfMonth = $today->copy()->endOfMonth();
$unreadAnnouncements = Cache::remember($cachePrefix.':unread-announcements', 60, function () use ($user) {
return DB::table('tbpengumuman')
->where('idProdi', $user['prodi'])
->whereIn('tujuan', ['A', 'D'])
->whereNotIn('id', function ($query) use ($user) {
$query->select('idkonten')
->from('tmp_notif')
->where('iduser', $user['id'])
->where('typeuser', 'D')
->where('jenis', 'P');
})
->count();
});
$unreadProposals = Cache::remember($cachePrefix.':unread-proposals', 60, function () use ($user) {
return DB::table('tbpraoutline')
->where('status_usulan', '0')
->whereNotIn('id', function ($query) use ($user) {
$query->select('idkonten')
->from('tmp_notif')
->where('iduser', $user['id'])
->where('typeuser', 'D')
->where('jenis', 'J');
})
->count();
});
$scheduleRows = Cache::remember($cachePrefix.':calendar:'.$startOfMonth->format('Y-m'), 60, function () use ($user, $startOfMonth, $endOfMonth) {
return DB::table('tbjadwal as tj')
->leftJoin('tbmhs as tm', 'tm.idmhs', '=', 'tj.idmhs')
->select([
'tj.id',
'tj.jenis',
'tj.start',
'tm.nmLengkap',
])
->where('tj.publish', 'Y')
->where('tj.idProdi', $user['prodi'])
->whereBetween('tj.start', [$startOfMonth->toDateTimeString(), $endOfMonth->copy()->endOfDay()->toDateTimeString()])
->orderBy('tj.start')
->get();
});
$upcomingSchedules = Cache::remember($cachePrefix.':upcoming', 60, function () use ($user, $today) {
return DB::table('tbjadwal as tj')
->leftJoin('tbmhs as tm', 'tm.idmhs', '=', 'tj.idmhs')
->select([
'tj.id',
'tj.jenis',
'tj.start',
'tj.ruangan',
'tj.judul',
'tm.nim',
'tm.nmLengkap',
])
->where('tj.publish', 'Y')
->where('tj.idProdi', $user['prodi'])
->whereNotNull('tj.start')
->where('tj.start', '>=', $today->copy()->startOfDay()->toDateTimeString())
->orderBy('tj.start')
->limit(5)
->get()
->map(fn ($row) => [
'id' => $row->id,
'jenis' => $this->scheduleLabel($row->jenis),
'jenisClass' => $this->scheduleBadgeClass($row->jenis),
'nama' => $row->nmLengkap ?: 'Mahasiswa tidak ditemukan',
'nim' => $row->nim ?: '-',
'judul' => $row->judul ?: 'Judul belum tersedia',
'ruangan' => $row->ruangan ?: '-',
'tanggal' => $this->formatIndonesianDateTime($row->start),
])
->all();
});
$calendar = $this->buildCalendar($scheduleRows);
$dashboard = [
'dateLabel' => $this->formatIndonesianDateTime(now()->toDateTimeString()),
'pageTitle' => 'Dashboard',
'sidebar' => DosenNavigation::build('dashboard.dosen'),
'menus' => [
['title' => 'Dashboard', 'href' => route('dashboard.dosen'), 'icon' => 'home', 'active' => true],
],
'legacyMenus' => [
'Utama' => [
['title' => 'Penawaran Judul', 'href' => $this->legacyUrl('dosen/dashboard.php?page=penawaran&menu=list-judul-saya'), 'icon' => 'briefcase'],
],
'Tugas Akhir 1' => [
['title' => 'Daftar Usulan', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=new'), 'icon' => 'folder'],
['title' => 'Review Saya', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=myreview'), 'icon' => 'chat'],
['title' => 'Pencarian Usulan', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=cari'), 'icon' => 'search'],
['title' => 'Daftar Bimbingan Saya', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=keputusan'), 'icon' => 'users'],
['title' => 'Statistik Usulan', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=statistik'), 'icon' => 'chart'],
['title' => 'Pemberitahuan', 'href' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=pemberitahuan'), 'icon' => 'bell'],
],
'Lainnya' => [
['title' => 'Pengumuman', 'href' => $this->legacyUrl('dosen/dashboard.php?page=pengumuman'), 'icon' => 'megaphone'],
['title' => 'Akun Pengguna', 'href' => $this->legacyUrl('dosen/dashboard.php?page=user&menu=my-profile'), 'icon' => 'user'],
['title' => 'Dokumen Sidang', 'href' => 'https://edoxid.untan.ac.id/', 'icon' => 'document'],
['title' => 'Early Warning', 'href' => $this->legacyUrl('dosen/dashboard.php?page=early-warning'), 'icon' => 'warning'],
['title' => 'Konsultasi Skripsi', 'href' => 'https://spota.untan.ac.id/konsultasi/', 'icon' => 'chat'],
['title' => 'Statistik Seminar', 'href' => 'https://spota.untan.ac.id/cek_banyak_sidang.php', 'icon' => 'chart'],
['title' => 'Konsultasi KP', 'href' => 'https://informatika.untan.ac.id/konsultasi/', 'icon' => 'chat'],
['title' => 'Pra LIRS (Dosen PA)', 'href' => $this->legacyUrl('dosen/dashboard.php?page=pra-lirs'), 'icon' => 'clipboard'],
['title' => 'Evaluasi Mahasiswa', 'href' => 'https://spota.untan.ac.id/steven/rekapMahasiswaEvaluasi.php?angkatan='.(date('Y') - 5).'&show=belumlulus', 'icon' => 'chart'],
],
],
'welcomeTitle' => 'Yth. Bapak/Ibu '.$user['nama_lengkap'],
'welcomeText' => 'Selamat datang di Sistem Pendukung Outline Tugas Akhir (SPOTA) Universitas Tanjungpura',
'androidLink' => $user['prodi'] === '2' ? $this->legacyUrl('spotaif.apk') : null,
'announcementNotice' => [
'count' => $unreadAnnouncements,
'title' => 'Pengumuman Terbaru',
'message' => $unreadAnnouncements > 0
? 'Terdapat '.$unreadAnnouncements.' Pengumuman Terbaru Yang Belum Dibaca'
: 'Tidak Ada Pengumuman Terbaru',
'primaryLabel' => 'Lihat Semua Pengumuman',
'primaryHref' => $this->legacyUrl('dosen/dashboard.php?page=pengumuman'),
],
'proposalNotice' => [
'count' => $unreadProposals,
'title' => 'Usulan Terbaru',
'message' => $unreadProposals > 0
? 'Terdapat '.$unreadProposals.' Usulan Terbaru.'
: 'Tidak terdapat Usulan terbaru.',
'primaryLabel' => $unreadProposals > 0 ? 'Lihat Usulan Terbaru' : 'Lihat Semua Usulan',
'primaryHref' => $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=new'),
'secondaryLabel' => $unreadProposals > 0 ? null : 'Cari Usulan',
'secondaryHref' => $unreadProposals > 0 ? null : $this->legacyUrl('dosen/dashboard.php?page=praoutline&menu=cari'),
],
'calendar' => $calendar,
'upcomingSchedules' => $upcomingSchedules,
];
return view('dashboard.dosen', [
'title' => 'Dashboard Dosen | SPOTA Rebuild',
'dashboard' => $dashboard,
'user' => $user,
]);
}
private function buildCalendar($scheduleRows): array
{
$today = now();
$startOfMonth = $today->copy()->startOfMonth();
$endOfMonth = $today->copy()->endOfMonth();
$startOfGrid = $startOfMonth->copy()->startOfWeek(Carbon::MONDAY);
$endOfGrid = $endOfMonth->copy()->endOfWeek(Carbon::SUNDAY);
$eventsByDate = [];
foreach ($scheduleRows as $row) {
if (! $row->start || strtotime($row->start) === false) {
continue;
}
$dateKey = Carbon::parse($row->start)->toDateString();
$eventsByDate[$dateKey][] = [
'id' => $row->id,
'title' => ucwords(strtolower((string) ($row->nmLengkap ?: 'Tanpa Nama'))),
'jenis' => $this->scheduleLabel($row->jenis),
'className' => $this->scheduleEventClass($row->jenis),
];
}
$weeks = [];
$cursor = $startOfGrid->copy();
while ($cursor->lessThanOrEqualTo($endOfGrid)) {
$week = [];
for ($day = 0; $day < 7; $day++) {
$dateKey = $cursor->toDateString();
$week[] = [
'date' => $dateKey,
'day' => $cursor->day,
'isCurrentMonth' => $cursor->month === $today->month,
'isToday' => $cursor->isToday(),
'events' => $eventsByDate[$dateKey] ?? [],
];
$cursor->addDay();
}
$weeks[] = $week;
}
return [
'monthLabel' => $this->formatMonthYear($today),
'weekdays' => ['Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab', 'Min'],
'weeks' => $weeks,
];
}
private function scheduleBadgeClass(?string $jenis): string
{
return match ($jenis) {
'Sidang' => 'bg-orange-100 text-orange-700',
'Outline' => 'bg-emerald-100 text-emerald-700',
'SidHas' => 'bg-amber-100 text-amber-700',
default => 'bg-slate-200 text-slate-700',
};
}
private function scheduleLabel(?string $jenis): string
{
return match ($jenis) {
'Sidang' => 'Sidang',
'Outline' => 'Outline',
'SidHas' => 'Seminar Hasil',
default => $jenis ?? 'Jadwal',
};
}
private function scheduleEventClass(?string $jenis): string
{
return match ($jenis) {
'Sidang' => 'bg-orange-100 text-orange-700 border-orange-200',
'Outline' => 'bg-emerald-100 text-emerald-700 border-emerald-200',
'SidHas' => 'bg-amber-100 text-amber-700 border-amber-200',
default => 'bg-slate-100 text-slate-700 border-slate-200',
};
}
private function formatIndonesianDateTime(?string $value): string
{
if (! $value) {
return '-';
}
return Carbon::parse($value)->locale('id')->translatedFormat('j F Y, H:i');
}
private function formatMonthYear(Carbon $date): string
{
return $date->copy()->locale('id')->translatedFormat('F Y');
}
private function legacyUrl(string $path): string
{
$baseUrl = rtrim((string) env('LEGACY_BASE_URL', 'http://127.0.0.1:8080'), '/');
return $baseUrl.'/'.ltrim($path, '/');
}
}