- Form NOC: tambah field nomor rekening lebih bayar (input number, readonly jika ada memo, hidden default, support old value & error handling) - Foto Lampiran: ubah layout jadi grid 4 kolom dengan shadow & hover effect, perbaikan urutan class Tailwind & judul kategori lebih prominent - Foto Lampiran: optimasi class container (relative, overflow-hidden, flex) & perbaikan spacing array $fotoTypes - LPJ Sederhana Standar: konsistensi class grid/flex/input-group, role 'penilai' ditambahkan untuk akses tombol simpan, perbaikan kondisi disabled button - Resume: optimasi class grid, flex, card-body, card-title, text, dan konsistensi urutan Tailwind di seluruh komponen - Konsistensi class: perbaikan di form, foto-lampiran, lpj-standar, resume agar mengikuti urutan Tailwind (layout → sizing → styling) - Struktur HTML: dirapikan untuk layout yang lebih responsif & semantik, dengan grid/flex yang lebih optimal - UX: tampilan foto lebih rapi, form lebih mudah digunakan, role-based access lebih jelas, field tambahan untuk kebutuhan bisnis - Dampak: data NOC lebih lengkap (tracking rekening lebih bayar), styling konsisten, UX meningkat, kode lebih maintainable
172 lines
7.3 KiB
PHP
172 lines
7.3 KiB
PHP
@isset($basicData['foto'])
|
||
@php
|
||
$photos = $formFoto['upload_foto'] ?? [];
|
||
if (!is_array($photos)) {
|
||
$photos = [];
|
||
}
|
||
$groupedPhotos = collect($photos)->groupBy('category');
|
||
@endphp
|
||
|
||
@if ($groupedPhotos->isEmpty())
|
||
<p class="text-gray-500">Tidak ada foto yang tersedia.</p>
|
||
@else
|
||
@foreach ($groupedPhotos as $category => $photos)
|
||
<div class="mt-5">
|
||
<h2 class="mb-3 text-xl font-bold text-gray-800">{{ $category ?? 'Tanpa Kategori' }}</h2>
|
||
<div class="p-4 rounded-lg border shadow-lg card">
|
||
<!-- Carousel Container -->
|
||
<div class="overflow-hidden relative w-full">
|
||
<div class="flex transition-transform duration-500 ease-in-out" id="carousel-{{ $category }}">
|
||
<span class="absolute top-0 right-2 text-white">
|
||
<i class="ki-filled ki-maximize"></i>
|
||
</span>
|
||
@foreach ($photos as $index => $item)
|
||
<div class="flex flex-col items-center min-w-full hover:cursor-pointer"
|
||
onclick="openPreview('{{ asset('storage/' . $item['path']) }}', '{{ $item['name'] }}', '{{ $item['description'] }}')">
|
||
|
||
<div class="overflow-hidden w-full rounded-md" style="height: 500px;">
|
||
@if (isset($item['path']))
|
||
<img src="{{ asset('storage/' . $item['path']) }}"
|
||
alt="Gambar {{ $index + 1 }}" class="object-cover w-full h-full">
|
||
@else
|
||
<p class="text-gray-500">Gambar tidak tersedia</p>
|
||
@endif
|
||
</div>
|
||
<h3 class="mt-3 text-lg font-semibold text-gray-600">
|
||
{{ $item['name'] ?? 'Foto - ' . ($index + 1) }}
|
||
</h3>
|
||
<p class="mt-1 text-sm text-gray-500">{{ $item['description'] ?? '-' }}</p>
|
||
|
||
</div>
|
||
@endforeach
|
||
</div>
|
||
|
||
<!-- Navigation Buttons -->
|
||
<button
|
||
class="absolute left-0 top-1/2 p-2 text-white bg-gray-800 rounded-full transform -translate-y-1/2 focus:outline-none"
|
||
onclick="prevSlide('{{ $category }}')">
|
||
<i class="ki-outline ki-left-square"></i>
|
||
</button>
|
||
<button
|
||
class="absolute right-0 top-1/2 p-2 text-white bg-gray-800 rounded-full transform -translate-y-1/2 focus:outline-none"
|
||
onclick="nextSlide('{{ $category }}')">
|
||
<i class="ki-outline ki-right-square"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endforeach
|
||
@endif
|
||
@endisset
|
||
|
||
<script>
|
||
let currentIndex = {};
|
||
|
||
function nextSlide(category) {
|
||
if (!currentIndex[category]) currentIndex[category] = 0;
|
||
|
||
const carousel = document.getElementById(`carousel-${category}`);
|
||
const totalSlides = carousel.children.length;
|
||
|
||
currentIndex[category] = (currentIndex[category] + 1) % totalSlides;
|
||
carousel.style.transform = `translateX(-${currentIndex[category] * 100}%)`;
|
||
}
|
||
|
||
function prevSlide(category) {
|
||
if (!currentIndex[category]) currentIndex[category] = 0;
|
||
|
||
const carousel = document.getElementById(`carousel-${category}`);
|
||
const totalSlides = carousel.children.length;
|
||
|
||
currentIndex[category] = (currentIndex[category] - 1 + totalSlides) % totalSlides;
|
||
carousel.style.transform = `translateX(-${currentIndex[category] * 100}%)`;
|
||
}
|
||
|
||
function openPreview(imagePath, name, description) {
|
||
const previewModal = document.createElement('div');
|
||
previewModal.className = 'fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50';
|
||
previewModal.innerHTML = `
|
||
<div class="relative">
|
||
<h3 class="mt-3 text-lg font-semibold text-center text-white">${name}</h3>
|
||
<img src="${imagePath}" class="object-contain max-w-full max-h-screen">
|
||
<button class="absolute top-2 right-2 p-2 text-white bg-red-500 rounded-full"
|
||
onclick="closePreview(this)">×</button>
|
||
|
||
<p class="mt-1 text-sm text-white">${description}</p>
|
||
</div>
|
||
`;
|
||
document.body.appendChild(previewModal);
|
||
}
|
||
|
||
|
||
function closePreview(button) {
|
||
const modal = button.closest('div.fixed');
|
||
if (modal) {
|
||
modal.remove();
|
||
}
|
||
}
|
||
</script>
|
||
|
||
|
||
@php
|
||
$fotoTypes = ['upload_gs', 'foto_sentuh_tanahku', 'foto_gistaru', 'foto_bhumi', 'foto_argis_region', 'foto_tempat'];
|
||
|
||
$customLabels = [
|
||
'upload_gs' => 'Gambar Situasi',
|
||
'foto_sentuh_tanahku' => 'Sentuh Tanahku',
|
||
'foto_gistaru' => 'Gistaru',
|
||
'foto_bhumi' => 'Bhumi',
|
||
'foto_argis_region' => 'Blad Tata Ruang',
|
||
'foto_tempat' => 'Tempat',
|
||
];
|
||
|
||
if (($key = array_search('upload_gs', $fotoTypes)) !== false) {
|
||
unset($fotoTypes[$key]);
|
||
array_unshift($fotoTypes, 'upload_gs');
|
||
}
|
||
$adaFoto = false;
|
||
if (isset($forminspeksi)) {
|
||
foreach ($fotoTypes as $type) {
|
||
$imagePath = $forminspeksi[$type] ?? null;
|
||
if ($imagePath && file_exists(storage_path('app/public/' . $imagePath))) {
|
||
$adaFoto = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
@endphp
|
||
|
||
@if ($adaFoto)
|
||
<div class="card">
|
||
<div class="card-header bg-agi-50" id="basic_settings">
|
||
<h3 class="uppercase card-title">
|
||
GS, Tata Ruang dan Peta
|
||
</h3>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="grid grid-cols-1 gap-4 lg:grid-cols-4">
|
||
@if (isset($forminspeksi))
|
||
@forelse ($fotoTypes as $type)
|
||
<div class="mb-4">
|
||
<h4 class="mb-2 text-lg font-semibold text-center text-gray-800">
|
||
{{ $customLabels[$type] ?? '' }}</h4>
|
||
<div class="p-4 rounded-lg border shadow transition-shadow photo-item hover:shadow-lg">
|
||
@php
|
||
$imagePath = $forminspeksi[$type] ?? null;
|
||
@endphp
|
||
|
||
@if ($imagePath && file_exists(storage_path('app/public/' . $imagePath)))
|
||
<img src="{{ asset('storage/' . $imagePath) }}" alt="{{ $type }}"
|
||
class="object-cover w-full h-auto rounded">
|
||
@endif
|
||
</div>
|
||
</div>
|
||
@empty
|
||
<p class="col-span-3 text-center text-gray-500">Tidak ada tipe foto yang tersedia</p>
|
||
@endforelse
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
@endif
|