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.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Support\AdminNavigation;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AdminDashboardController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): View
|
||||
{
|
||||
$auth = $request->session()->get('legacy_auth');
|
||||
|
||||
abort_unless(($auth['role'] ?? null) === 'admin', 403);
|
||||
|
||||
$user = $auth['user'];
|
||||
$isSuper = ($user['lvl'] ?? null) === 'S';
|
||||
|
||||
$stats = $isSuper ? [
|
||||
['label' => 'Fakultas', 'value' => (string) DB::table('tbfakultas')->count(), 'note' => 'Total data fakultas pada basis data SPOTA.'],
|
||||
['label' => 'Jurusan', 'value' => (string) DB::table('tbjurusan')->count(), 'note' => 'Total data jurusan lintas fakultas.'],
|
||||
['label' => 'Program Studi', 'value' => (string) DB::table('tbprodi')->count(), 'note' => 'Total program studi yang tercatat.'],
|
||||
['label' => 'Admin Aktif', 'value' => (string) DB::table('tbadmin')->where('aktif', 'Y')->count(), 'note' => 'Akun administrator aktif.'],
|
||||
] : [
|
||||
['label' => 'Mahasiswa', 'value' => (string) DB::table('tbmhs')->where('idProdi', $user['prodi'])->count(), 'note' => 'Data mahasiswa pada program studi admin.'],
|
||||
['label' => 'Dosen', 'value' => (string) DB::table('tbdosen')->where('idProdi', $user['prodi'])->count(), 'note' => 'Data dosen pada program studi admin.'],
|
||||
['label' => 'Draft Praoutline', 'value' => (string) DB::table('tbpraoutline')->where('idProdi', $user['prodi'])->count(), 'note' => 'Total draft praoutline program studi.'],
|
||||
['label' => 'Jadwal Publish', 'value' => (string) DB::table('tbjadwal')->where('idProdi', $user['prodi'])->where('publish', 'Y')->count(), 'note' => 'Jadwal seminar/sidang yang dipublikasi.'],
|
||||
];
|
||||
|
||||
$schedules = DB::table('tbjadwal as tj')
|
||||
->leftJoin('tbmhs as tm', 'tj.idMhs', '=', 'tm.idmhs')
|
||||
->select(['tj.jenis', 'tj.start', 'tj.ruangan', 'tm.nmLengkap as mahasiswa'])
|
||||
->when(! $isSuper, fn ($query) => $query->where('tj.idProdi', $user['prodi']))
|
||||
->whereNotNull('tj.start')
|
||||
->orderByDesc('tj.start')
|
||||
->limit(6)
|
||||
->get()
|
||||
->map(fn ($item) => [
|
||||
'jenis' => $this->scheduleLabel($item->jenis),
|
||||
'tanggal' => $this->formatDateTime($item->start),
|
||||
'ruangan' => $item->ruangan ?: '-',
|
||||
'mahasiswa' => $item->mahasiswa ?: '-',
|
||||
])
|
||||
->all();
|
||||
|
||||
return view('dashboard.admin', [
|
||||
'title' => 'Dashboard Admin | SPOTA Rebuild',
|
||||
'user' => $user,
|
||||
'sidebar' => AdminNavigation::build($user),
|
||||
'pageDate' => Carbon::now()->locale('id')->translatedFormat('j F Y, H:i'),
|
||||
'stats' => $stats,
|
||||
'schedules' => $schedules,
|
||||
]);
|
||||
}
|
||||
|
||||
private function scheduleLabel(?string $jenis): string
|
||||
{
|
||||
return match ($jenis) {
|
||||
'Sidang' => 'Sidang',
|
||||
'Outline' => 'Outline',
|
||||
'SidHas' => 'Seminar Hasil',
|
||||
default => $jenis ?? 'Jadwal',
|
||||
};
|
||||
}
|
||||
|
||||
private function formatDateTime(?string $value): string
|
||||
{
|
||||
if (! $value) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return Carbon::parse($value)->locale('id')->translatedFormat('j F Y, H:i');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
<?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, '/');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class MahasiswaDashboardController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request): View
|
||||
{
|
||||
$auth = $request->session()->get('legacy_auth');
|
||||
|
||||
abort_unless(($auth['role'] ?? null) === 'mahasiswa', 403);
|
||||
|
||||
$user = $auth['user'];
|
||||
|
||||
$latestPraoutline = DB::table('tbpraoutline as tp')
|
||||
->leftJoin('tbrekaphasil as trh', 'tp.id', '=', 'trh.idpraoutline')
|
||||
->select(['tp.id', 'tp.judul', 'tp.status_usulan', 'trh.ket'])
|
||||
->where('tp.nim', $user['nim'])
|
||||
->where('tp.idProdi', $user['prodi'])
|
||||
->orderByDesc('tp.id')
|
||||
->first();
|
||||
|
||||
$unreadAnnouncements = DB::table('tbpengumuman')
|
||||
->where('idProdi', $user['prodi'])
|
||||
->whereIn('tujuan', ['A', 'M'])
|
||||
->whereNotIn('id', function ($query) use ($user) {
|
||||
$query->select('idkonten')
|
||||
->from('tmp_notif')
|
||||
->where('iduser', $user['id'])
|
||||
->where('typeuser', 'M')
|
||||
->where('jenis', 'P');
|
||||
})
|
||||
->count();
|
||||
|
||||
$publishedSchedules = DB::table('tbjadwal')
|
||||
->where('idProdi', $user['prodi'])
|
||||
->where('publish', 'Y')
|
||||
->count();
|
||||
|
||||
$nextSchedule = DB::table('tbjadwal')
|
||||
->select(['jenis', 'start', 'ruangan'])
|
||||
->where('idMhs', $user['id'])
|
||||
->where('publish', 'Y')
|
||||
->whereNotNull('start')
|
||||
->orderBy('start')
|
||||
->first();
|
||||
|
||||
$activeDrafts = DB::table('tbpraoutline')
|
||||
->where('nim', $user['nim'])
|
||||
->whereIn('status_usulan', ['0', '1'])
|
||||
->count();
|
||||
|
||||
$statusAlert = match ($latestPraoutline?->status_usulan) {
|
||||
'0' => [
|
||||
'title' => 'Draft Praoutline Masih Dalam Proses Review',
|
||||
'description' => 'Silakan cek menu review untuk melihat tanggapan dosen terhadap draft yang sedang berjalan.',
|
||||
'button' => 'Lihat Review',
|
||||
'buttonHref' => route('mahasiswa.status-usulan', [], false),
|
||||
'class' => 'border-sky-200 bg-sky-50 text-sky-900',
|
||||
'buttonClass' => 'bg-sky-600 text-white hover:opacity-90',
|
||||
],
|
||||
'1' => [
|
||||
'title' => 'Draft Praoutline Anda Telah Disetujui',
|
||||
'description' => 'Judul terakhir sudah memperoleh persetujuan. Silakan pantau tahapan berikutnya pada modul yang terkait.',
|
||||
'button' => 'Lihat Putusan',
|
||||
'buttonHref' => route('mahasiswa.status-usulan', [], false),
|
||||
'class' => 'border-emerald-200 bg-emerald-50 text-emerald-900',
|
||||
'buttonClass' => 'bg-emerald-600 text-white hover:opacity-90',
|
||||
],
|
||||
'2' => [
|
||||
'title' => 'Judul yang Anda Ajukan Tidak Disetujui',
|
||||
'description' => $latestPraoutline?->ket ?: 'Silakan periksa catatan keputusan dan siapkan upload judul baru.',
|
||||
'button' => 'Lihat Catatan Putusan',
|
||||
'buttonHref' => route('mahasiswa.status-usulan', [], false),
|
||||
'class' => 'border-rose-200 bg-rose-50 text-rose-900',
|
||||
'buttonClass' => 'bg-rose-600 text-white hover:opacity-90',
|
||||
],
|
||||
default => [
|
||||
'title' => 'Belum Ada Draft Praoutline Aktif',
|
||||
'description' => 'Mahasiswa ini belum memiliki usulan judul aktif yang tercatat pada data SPOTA saat ini.',
|
||||
'button' => 'Ajukan Outline Baru',
|
||||
'buttonHref' => route('mahasiswa.praoutline.upload', [], false),
|
||||
'class' => 'border-slate-200 bg-slate-50 text-slate-900',
|
||||
'buttonClass' => 'bg-[#15171A] text-white hover:opacity-90',
|
||||
],
|
||||
};
|
||||
|
||||
$announcementAlert = [
|
||||
'title' => 'Pengumuman Terbaru',
|
||||
'description' => $unreadAnnouncements > 0
|
||||
? 'Terdapat '.$unreadAnnouncements.' pengumuman program studi yang belum dibaca.'
|
||||
: 'Tidak terdapat pengumuman baru yang perlu dibaca saat ini.',
|
||||
'button' => 'Lihat Semua Pengumuman',
|
||||
'buttonHref' => route('mahasiswa.pengumuman.index', [], false),
|
||||
'class' => 'border-amber-200 bg-amber-50 text-amber-900',
|
||||
'buttonClass' => 'bg-amber-400 text-[#15171A] hover:bg-amber-300',
|
||||
];
|
||||
|
||||
$dashboard = [
|
||||
'eyebrow' => 'Dashboard Mahasiswa',
|
||||
'title' => 'Halo, '.$user['nama_lengkap'].'.',
|
||||
'description' => 'Selamat datang di Sistem Pendukung Outline Tugas Akhir (SPOTA) Universitas Tanjungpura.',
|
||||
'menus' => [
|
||||
['title' => 'Dashboard', 'href' => route('dashboard.mahasiswa'), 'icon' => 'home', 'active' => true],
|
||||
['title' => 'Informasi', 'icon' => 'folder', 'children' => [
|
||||
['title' => 'Status Usulan', 'href' => route('mahasiswa.status-usulan', [], false), 'icon' => 'chart'],
|
||||
['title' => 'Ajukan Outline Baru', 'href' => route('mahasiswa.praoutline.upload', [], false), 'icon' => 'clipboard'],
|
||||
['title' => 'Penawaran Judul', 'href' => route('mahasiswa.penawaran.index', [], false), 'icon' => 'briefcase'],
|
||||
['title' => 'Pengumuman', 'href' => route('mahasiswa.pengumuman.index', [], false), 'icon' => 'bell'],
|
||||
['title' => 'Jadwal Terdekat', 'href' => '#jadwal', 'icon' => 'clock'],
|
||||
]],
|
||||
],
|
||||
'stats' => [
|
||||
['label' => 'Status Usulan Terakhir', 'value' => $this->statusLabel($latestPraoutline?->status_usulan), 'delta' => $latestPraoutline ? 'Draft #'.$latestPraoutline->id : 'Belum ada draft', 'deltaClass' => $this->statusDeltaClass($latestPraoutline?->status_usulan), 'note' => $latestPraoutline?->judul ? $latestPraoutline->judul : 'Belum ada judul yang tercatat di sistem.'],
|
||||
['label' => 'Pengumuman Belum Dibaca', 'value' => (string) $unreadAnnouncements, 'delta' => $unreadAnnouncements > 0 ? 'Perlu dibaca' : 'Sudah aman', 'deltaClass' => $unreadAnnouncements > 0 ? 'bg-amber-100 text-amber-800' : 'bg-emerald-100 text-emerald-800', 'note' => 'Jumlah pengumuman program studi yang belum dibaca.'],
|
||||
['label' => 'Jadwal Terdekat', 'value' => $nextSchedule ? $this->scheduleLabel($nextSchedule->jenis) : '-', 'delta' => $nextSchedule ? 'Terjadwal' : 'Belum ada jadwal', 'deltaClass' => $nextSchedule ? 'bg-sky-100 text-sky-800' : 'bg-slate-200 text-slate-700', 'note' => $nextSchedule ? $this->formatDateTime($nextSchedule->start).' · '.$nextSchedule->ruangan : 'Belum ada jadwal seminar yang dipublikasikan untuk mahasiswa ini.'],
|
||||
['label' => 'Draft Aktif', 'value' => (string) $activeDrafts, 'delta' => $activeDrafts > 0 ? 'Masih berjalan' : 'Tidak ada', 'deltaClass' => $activeDrafts > 0 ? 'bg-violet-100 text-violet-800' : 'bg-slate-200 text-slate-700', 'note' => 'Jumlah draft yang masih aktif pada data SPOTA.'],
|
||||
],
|
||||
'latestTitle' => $latestPraoutline?->judul,
|
||||
'statusAlert' => $statusAlert,
|
||||
'announcementAlert' => $announcementAlert,
|
||||
'nextSchedule' => $nextSchedule ? [
|
||||
'jenis' => $this->scheduleLabel($nextSchedule->jenis),
|
||||
'tanggal' => $this->formatDateTime($nextSchedule->start),
|
||||
'ruangan' => $nextSchedule->ruangan ?: '-',
|
||||
] : null,
|
||||
'publishedSchedules' => $publishedSchedules,
|
||||
];
|
||||
|
||||
return view('dashboard.mahasiswa', [
|
||||
'title' => 'Dashboard Mahasiswa | SPOTA Rebuild',
|
||||
'dashboard' => $dashboard,
|
||||
'user' => $user,
|
||||
]);
|
||||
}
|
||||
|
||||
private function statusLabel(?string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'0' => 'Dalam Review',
|
||||
'1' => 'Disetujui',
|
||||
'2' => 'Ditolak',
|
||||
default => 'Belum Ada Draft',
|
||||
};
|
||||
}
|
||||
|
||||
private function statusDeltaClass(?string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'0' => 'bg-sky-100 text-sky-800',
|
||||
'1' => 'bg-emerald-100 text-emerald-800',
|
||||
'2' => 'bg-rose-100 text-rose-800',
|
||||
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 formatDateTime(?string $value): string
|
||||
{
|
||||
if (! $value) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return Carbon::parse($value)->locale('id')->translatedFormat('j F Y, H:i');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user