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:
Power BI Dev
2026-05-03 18:50:29 +07:00
parent 89ce9d30a7
commit dab8ea396b
107 changed files with 17544 additions and 20 deletions

View File

@@ -0,0 +1,22 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user" :page-actions="$pageActions ?? []">
<article class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
<div class="min-w-0 flex-1">
<h2 class="break-words text-[24px] font-semibold leading-8 text-[#15171A]">{{ $penawaran->judul }}</h2>
<div class="mt-3 flex flex-wrap gap-3 text-sm text-[#6B7280]">
<span>Ditawarkan oleh: {{ $penawaran->dosen ?: '-' }}</span>
<span>KK: {{ $penawaran->kk ?: '-' }}</span>
<span>{{ $penawaran->waktuInput ? \Carbon\Carbon::parse($penawaran->waktuInput)->locale('id')->translatedFormat('j F Y, H:i') : '-' }}</span>
</div>
</div>
<form method="POST" action="{{ route('mahasiswa.penawaran.book', ['id' => $penawaran->idPenawaran]) }}" class="shrink-0">
@csrf
<button type="submit" class="rounded-md bg-[#15171A] px-5 py-2.5 text-sm font-medium text-white hover:opacity-90">Booking Judul Ini</button>
</form>
</div>
<div class="prose prose-sm mt-6 max-w-none rounded-xl border border-[#E5E7EB] bg-[#F9FAFB] p-5 text-[#374151] prose-p:leading-7">
{!! $penawaran->deskripsi ?: '<p>Tidak ada deskripsi.</p>' !!}
</div>
</article>
</x-mahasiswa.partials.page-shell>

View File

@@ -0,0 +1,82 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user">
<section class="space-y-5">
<form method="GET" action="{{ route('mahasiswa.penawaran.index') }}" class="rounded-xl border border-[#E5E7EB] bg-white p-5 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="grid gap-4 lg:grid-cols-[220px_minmax(0,1fr)_auto] lg:items-end">
<div>
<label class="text-sm font-semibold text-[#15171A]">Status Judul</label>
<select name="status" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm">
<option value="0" @selected($filters['status'] === '0')>Belum Diambil</option>
<option value="1" @selected($filters['status'] === '1')>Sudah Diambil</option>
<option value="Semua" @selected($filters['status'] === 'Semua')>Semua Status</option>
</select>
</div>
<div>
<label class="text-sm font-semibold text-[#15171A]">Tampilkan</label>
<select name="kk" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm">
<option value="Semua" @selected($filters['kk'] === 'Semua')>Semua Kelompok Keahlian</option>
@foreach ($kelompokKeahlian as $kk)
<option value="{{ $kk->idKK }}" @selected((string) $filters['kk'] === (string) $kk->idKK)>{{ $kk->namaKK }}</option>
@endforeach
</select>
</div>
<button type="submit" class="rounded-md bg-[#15171A] px-5 py-3 text-sm font-medium text-white hover:opacity-90">Filter</button>
</div>
</form>
<section class="overflow-hidden rounded-xl border border-[#E5E7EB] bg-white shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="overflow-x-auto">
<table class="min-w-[980px] w-full text-left text-sm">
<thead class="bg-[#F9FAFB] text-xs uppercase tracking-[0.12em] text-[#6B7280]">
<tr>
<th class="px-4 py-3">No.</th>
<th class="px-4 py-3">Judul</th>
<th class="px-4 py-3">Ditawarkan Oleh</th>
<th class="px-4 py-3">KK</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Diambil Oleh</th>
<th class="px-4 py-3 text-right">Aksi</th>
</tr>
</thead>
<tbody class="divide-y divide-[#E5E7EB]">
@forelse ($penawaran as $item)
@php
$available = is_null($item->statusPengambilan) || $item->statusPengambilan === '2';
@endphp
<tr>
<td class="px-4 py-4 text-[#6B7280]">{{ $loop->iteration + ($penawaran->currentPage() - 1) * $penawaran->perPage() }}</td>
<td class="px-4 py-4">
<a href="{{ route('mahasiswa.penawaran.show', ['id' => $item->idPenawaran], false) }}" class="font-semibold text-[#15171A] hover:text-[#625DF5]">{{ $item->judul }}</a>
<p class="mt-1 line-clamp-2 text-xs leading-5 text-[#6B7280]">{{ str($item->deskripsi)->stripTags()->squish()->limit(120) }}</p>
</td>
<td class="px-4 py-4 text-[#374151]">{{ $item->dosen ?: '-' }}</td>
<td class="px-4 py-4 text-[#374151]">{{ $item->kk ?: '-' }}</td>
<td class="px-4 py-4">
<span class="rounded-full px-2.5 py-1 text-xs font-semibold {{ $available ? 'bg-emerald-100 text-emerald-800' : 'bg-amber-100 text-amber-800' }}">{{ $available ? 'Belum Diambil' : 'Sudah Diambil' }}</span>
</td>
<td class="px-4 py-4 text-[#374151]">{{ $item->diambil_oleh ?: '-' }}</td>
<td class="px-4 py-4">
<div class="flex justify-end gap-2 whitespace-nowrap">
<a href="{{ route('mahasiswa.penawaran.show', ['id' => $item->idPenawaran], false) }}" class="rounded-md border border-[#D1D5DB] px-3 py-2 text-xs font-medium text-[#15171A] hover:bg-[#F9FAFB]">Lihat</a>
@if ($available)
<form method="POST" action="{{ route('mahasiswa.penawaran.book', ['id' => $item->idPenawaran]) }}">
@csrf
<button type="submit" class="rounded-md bg-[#15171A] px-3 py-2 text-xs font-medium text-white hover:opacity-90">Booking</button>
</form>
@endif
</div>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-4 py-8 text-center text-[#6B7280]">Tidak ada penawaran judul sesuai filter.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="border-t border-[#E5E7EB] px-4 py-3">
{{ $penawaran->links() }}
</div>
</section>
</section>
</x-mahasiswa.partials.page-shell>

View File

@@ -0,0 +1,9 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user" :page-actions="$pageActions ?? []">
<article class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<h2 class="text-[24px] font-semibold leading-8 text-[#15171A]">{{ $pengumuman['judul'] }}</h2>
<p class="mt-3 text-sm text-[#6B7280]">{{ $pengumuman['tgl'] }}</p>
<div class="prose prose-sm mt-6 max-w-none text-[#374151] prose-p:leading-7">
{!! $pengumuman['isi'] !!}
</div>
</article>
</x-mahasiswa.partials.page-shell>

View File

@@ -0,0 +1,18 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user">
<section class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="space-y-4">
@forelse ($pengumuman as $item)
<article class="rounded-xl border border-[#E5E7EB] bg-[#F9FAFB] p-5">
<a href="{{ $item['detailHref'] }}" class="text-lg font-semibold text-[#15171A] hover:text-[#625DF5]">{{ $item['judul'] }}</a>
<p class="mt-2 text-sm text-[#6B7280]">{{ \Carbon\Carbon::parse($item['tgl'])->locale('id')->translatedFormat('j F Y, H:i') }}</p>
<p class="mt-4 text-sm leading-7 text-[#4B5563]">{{ $item['preview'] }}</p>
<div class="mt-4 flex flex-wrap gap-2">
<a href="{{ $item['detailHref'] }}" class="rounded-md bg-[#15171A] px-3 py-2 text-xs font-medium text-white hover:opacity-90">Lihat Detail</a>
</div>
</article>
@empty
<div class="rounded-xl border border-dashed border-[#D1D5DB] bg-[#F9FAFB] p-6 text-center text-[#6B7280]">Belum ada pengumuman untuk mahasiswa.</div>
@endforelse
</div>
</section>
</x-mahasiswa.partials.page-shell>

View File

@@ -0,0 +1,71 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user" :page-actions="$pageActions ?? []">
<section class="space-y-5">
@if ($outline)
<article class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
<div class="min-w-0 flex-1">
<h2 class="break-words text-[22px] font-semibold leading-8 text-[#15171A]">{{ $outline['judul'] }}</h2>
<div class="mt-3 flex flex-wrap gap-3 text-sm text-[#6B7280]">
<span>Draft #{{ $outline['id'] }}</span>
<span>{{ $outline['tanggal'] }}</span>
<span>KK: {{ $outline['kelompokKeahlian'] }}</span>
</div>
</div>
<div class="shrink-0 rounded-full px-3 py-1 text-xs font-semibold {{ $outline['statusClass'] }}">
{{ $outline['status'] }}
</div>
</div>
<div class="mt-5 rounded-xl border border-[#E5E7EB] bg-[#F9FAFB] p-4 text-sm leading-7 text-[#374151]">
{!! $outline['deskripsi'] ?: '<span class="text-[#6B7280]">Tidak ada deskripsi usulan.</span>' !!}
</div>
@if ($outline['catatan'])
<div class="mt-5 rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm leading-7 text-amber-900">
<p class="font-semibold">Catatan Putusan</p>
<p class="mt-2">{{ $outline['catatan'] }}</p>
</div>
@endif
</article>
<section class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<div class="flex items-center justify-between gap-3">
<div>
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[#979797]">Diskusi</p>
<h3 class="mt-2 text-xl font-semibold text-[#15171A]">Riwayat Review</h3>
</div>
<span class="rounded-full border border-[#E5E7EB] bg-[#F9FAFB] px-3 py-1 text-xs font-semibold text-[#4B5563]">{{ count($reviews) }} entri</span>
</div>
<div class="mt-5 space-y-4">
@forelse ($reviews as $review)
<article class="rounded-xl border border-[#E5E7EB] bg-[#F9FAFB] p-5">
<div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div>
<div class="flex flex-wrap items-center gap-2">
<p class="font-semibold text-[#15171A]">{{ $review['author'] }}</p>
<span class="rounded-full bg-white px-2.5 py-1 text-[11px] font-semibold text-[#4B5563]">{{ $review['role'] }}</span>
<span class="rounded-full bg-white px-2.5 py-1 text-[11px] font-semibold text-[#4B5563]">{{ $review['type'] }}</span>
@if ($review['decision'])
<span class="rounded-full px-2.5 py-1 text-[11px] font-semibold {{ $review['decision'] === 'Setuju' ? 'bg-emerald-100 text-emerald-700' : 'bg-rose-100 text-rose-700' }}">{{ $review['decision'] }}</span>
@endif
</div>
<p class="mt-2 text-xs text-[#6B7280]">{{ $review['timestamp'] }}</p>
</div>
</div>
<div class="prose prose-sm mt-4 max-w-none text-[#374151] prose-p:leading-7">
{!! $review['body'] !!}
</div>
</article>
@empty
<div class="rounded-xl border border-dashed border-[#D1D5DB] bg-[#F9FAFB] p-6 text-center text-[#6B7280]">Belum ada review untuk usulan terbaru.</div>
@endforelse
</div>
</section>
@else
<div class="rounded-xl border border-dashed border-[#D1D5DB] bg-white p-8 text-center text-[#6B7280] shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
Belum ada draft praoutline yang tercatat untuk akun mahasiswa ini.
</div>
@endif
</section>
</x-mahasiswa.partials.page-shell>

View File

@@ -0,0 +1,89 @@
<x-mahasiswa.partials.page-shell :title="$title" :sidebar="$sidebar" :page-title="$pageTitle" :page-description="$pageDescription" :page-date="$pageDate" :user="$user">
@if ($hasActiveDraft)
<section class="rounded-xl border border-sky-200 bg-sky-50 p-6 text-sky-900 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
<h2 class="text-xl font-semibold">Draft Praoutline Anda Telah Diupload</h2>
<p class="mt-3 text-sm leading-7">Anda masih memiliki draft aktif. Silakan lihat status usulan dan riwayat review sebelum mengajukan draft baru.</p>
<div class="mt-5">
<a href="{{ route('mahasiswa.status-usulan', [], false) }}" class="inline-flex rounded-md bg-sky-600 px-4 py-2.5 text-sm font-medium text-white hover:opacity-90">Lihat Review</a>
</div>
</section>
@else
<section class="space-y-5">
<div class="rounded-xl border border-amber-200 bg-amber-50 p-5 text-sm leading-7 text-amber-900">
<p class="font-semibold">Perhatian</p>
<p class="mt-2">Pastikan file yang diupload berupa PDF dan draft sudah diperiksa. Jika terdapat kesalahan upload, hubungi administrator prodi.</p>
</div>
<form method="POST" action="{{ route('mahasiswa.praoutline.store') }}" enctype="multipart/form-data" class="rounded-xl border border-[#E5E7EB] bg-white p-6 shadow-[0_8px_12px_rgba(13,10,44,0.04)]">
@csrf
<div class="grid gap-5">
<div>
<label class="text-sm font-semibold text-[#15171A]">Judul Skripsi</label>
<input type="text" name="judul" value="{{ old('judul') }}" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none" required>
</div>
<div>
<label class="text-sm font-semibold text-[#15171A]">Deskripsi</label>
<textarea name="deskripsi" rows="7" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none">{{ old('deskripsi') }}</textarea>
</div>
<div class="grid gap-5 lg:grid-cols-2">
<div>
<label class="text-sm font-semibold text-[#15171A]">Berkas PDF</label>
<input type="file" name="berkas" accept="application/pdf" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm" required>
</div>
<div>
<label class="text-sm font-semibold text-[#15171A]">Kelompok Keahlian Tujuan</label>
<select name="kelompokKeahlian" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none" required>
<option value="">Pilih Kelompok Keahlian</option>
@foreach ($kelompokKeahlian as $kk)
<option value="{{ $kk->idKK }}" @selected(old('kelompokKeahlian') == $kk->idKK)>{{ $kk->namaKK }}</option>
@endforeach
</select>
</div>
</div>
<div class="grid gap-5 lg:grid-cols-2">
<div>
<label class="text-sm font-semibold text-[#15171A]">Dosen Pembimbing Akademik (PA)</label>
<select name="dosenpa" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none" required>
<option value="">Pilih Dosen</option>
@foreach ($dosen as $item)
<option value="{{ $item->nmLengkap }}" @selected(old('dosenpa') === $item->nmLengkap)>{{ $item->nmLengkap }}</option>
@endforeach
</select>
</div>
<div>
<label class="text-sm font-semibold text-[#15171A]">Dosen Yang Merekomendasikan Judul</label>
<select name="drekomjudul" class="mt-2 w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none">
<option value="">Pilih Dosen</option>
@foreach ($dosen as $item)
<option value="{{ $item->nmLengkap }}" @selected(old('drekomjudul') === $item->nmLengkap)>{{ $item->nmLengkap }}</option>
@endforeach
</select>
</div>
</div>
<div>
<p class="text-sm font-semibold text-[#15171A]">Pilihan Dosen Pembimbing</p>
<div class="mt-2 grid gap-3 lg:grid-cols-2">
@for ($i = 1; $i <= 4; $i++)
<select name="pilpemb{{ $i }}" class="w-full rounded-md border border-[#D1D5DB] px-4 py-3 text-sm focus:border-[#625DF5] focus:outline-none">
<option value="">Pilihan {{ $i }}</option>
@foreach ($dosen as $item)
<option value="{{ $item->nmLengkap }}" @selected(old('pilpemb'.$i) === $item->nmLengkap)>{{ $item->nmLengkap }}</option>
@endforeach
</select>
@endfor
</div>
</div>
<div class="flex flex-wrap gap-3 border-t border-[#E5E7EB] pt-5">
<button type="submit" class="rounded-md bg-[#15171A] px-5 py-2.5 text-sm font-medium text-white hover:opacity-90">Upload Draft</button>
<a href="{{ route('mahasiswa.status-usulan', [], false) }}" class="rounded-md border border-[#D1D5DB] bg-white px-5 py-2.5 text-sm font-medium text-[#15171A] hover:bg-[#F9FAFB]">Batal</a>
</div>
</div>
</form>
</section>
@endif
</x-mahasiswa.partials.page-shell>