[templete]

This commit is contained in:
Arief Dwi Wicaksono 2025-09-18 13:18:35 +07:00
parent c53e42a12f
commit c720cc460f

View File

@ -21,7 +21,7 @@
@endif @endif
</div> </div>
<!-- Flash & Errors (sama seperti sebelumnya) --> <!-- Flash & Errors -->
@if (session('success')) @if (session('success'))
<div id="toast-success" class="mb-4 p-3 rounded bg-green-100 text-green-800 border border-green-300 shadow"> <div id="toast-success" class="mb-4 p-3 rounded bg-green-100 text-green-800 border border-green-300 shadow">
{{ session('success') }} {{ session('success') }}
@ -67,8 +67,6 @@
</td> </td>
<td class="p-2 border border-gray-300 truncate">{{ $template->nama_template }}</td> <td class="p-2 border border-gray-300 truncate">{{ $template->nama_template }}</td>
<td class="p-2 border border-gray-300 truncate">{{ $template->kategori->nama ?? '-' }}</td> <td class="p-2 border border-gray-300 truncate">{{ $template->kategori->nama ?? '-' }}</td>
<!-- Tampilkan banyak fitur -->
<td class="p-2 border border-gray-300 align-top"> <td class="p-2 border border-gray-300 align-top">
<div class="flex flex-wrap gap-1"> <div class="flex flex-wrap gap-1">
@forelse($template->fiturs as $f) @forelse($template->fiturs as $f)
@ -106,15 +104,13 @@
data-name="{{ $template->nama_template }}"> data-name="{{ $template->nama_template }}">
<i class="bi bi-trash mr-1"></i> Hapus <i class="bi bi-trash mr-1"></i> Hapus
</button> </button>
</form> </form>
</div> </div>
</td> </td>
</tr> </tr>
@empty @empty
<tr> <tr>
<td colspan="7" class="p-2 text-center text-gray-500 border border-gray-300">Belum ada <td colspan="7" class="p-2 text-center text-gray-500 border border-gray-300">Belum ada template</td>
template</td>
</tr> </tr>
@endforelse @endforelse
</tbody> </tbody>
@ -122,183 +118,106 @@
</div> </div>
</div> </div>
<!-- Modal Konfirmasi Hapus Template -->
<div id="modalDeleteTemplate" class="fixed inset-0 hidden items-center justify-center z-50">
<div class="absolute inset-0 bg-black opacity-50" id="modalDeleteTemplateOverlay"></div>
<div class="bg-white rounded-lg shadow-lg w-full max-w-md z-50 overflow-hidden">
<form id="deleteTemplateForm" method="POST">
@csrf
@method('DELETE')
<div class="p-4 border-b">
<h5 class="text-lg font-medium">Hapus Template</h5>
</div>
<div class="p-4">
Apakah Anda yakin ingin menghapus template <strong id="deleteTemplateName"></strong>?
</div>
<div class="p-4 border-t flex justify-end space-x-2">
<button type="button" id="closeDeleteTemplateModal"
class="bg-gray-300 text-black px-3 py-1 rounded">Batal</button>
<button type="submit" class="bg-red-600 text-white px-3 py-1 rounded">Ya, Hapus</button>
</div>
</form>
</div>
</div>
<!-- Pagination -->
@if ($templates->hasPages())
<div class="p-4 flex justify-center">
<div class="flex space-x-1">
{{-- Tombol Previous --}}
@if ($templates->onFirstPage())
<span class="px-3 py-1 rounded-lg bg-gray-200 text-gray-500 cursor-not-allowed">Prev</span>
@else
<a href="{{ $templates->previousPageUrl() }}"
class="px-3 py-1 rounded-lg bg-gray-200 text-gray-700 hover:bg-gray-300">Prev</a>
@endif
@php
$total = $templates->lastPage();
$current = $templates->currentPage();
@endphp
{{-- Selalu tampilkan halaman pertama --}}
@if ($current > 2)
<a href="{{ $templates->url(1) }}"
class="px-3 py-1 rounded-lg bg-gray-200 text-gray-700 hover:bg-blue-100">1</a>
@if ($current > 3)
<span class="px-3 py-1 text-gray-500">...</span>
@endif
@endif
{{-- Hanya tampilkan 3 halaman di tengah --}}
@for ($i = max(1, $current - 1); $i <= min($total, $current + 1); $i++)
@if ($i == $current)
<span
class="px-3 py-1 rounded-lg bg-blue-600 text-white font-semibold">{{ $i }}</span>
@else
<a href="{{ $templates->url($i) }}"
class="px-3 py-1 rounded-lg bg-gray-200 text-gray-700 hover:bg-blue-100">{{ $i }}</a>
@endif
@endfor
{{-- Selalu tampilkan halaman terakhir --}}
@if ($current < $total - 1)
@if ($current < $total - 2)
<span class="px-3 py-1 text-gray-500">...</span>
@endif
<a href="{{ $templates->url($total) }}"
class="px-3 py-1 rounded-lg bg-gray-200 text-gray-700 hover:bg-blue-100">{{ $total }}</a>
@endif
{{-- Tombol Next --}}
@if ($templates->hasMorePages())
<a href="{{ $templates->nextPageUrl() }}"
class="px-3 py-1 rounded-lg bg-gray-200 text-gray-700 hover:bg-gray-300">Next</a>
@else
<span class="px-3 py-1 rounded-lg bg-gray-200 text-gray-500 cursor-not-allowed">Next</span>
@endif
</div>
</div>
@endif
<!-- Modal Tambah Template --> <!-- Modal Tambah Template -->
@if (!isset($kategori)) @if (!isset($kategori))
<div id="modalTambah" class="fixed inset-0 hidden items-center justify-center z-50"> <div id="modalTambah" class="fixed inset-0 hidden items-center justify-center z-50">
<div class="absolute inset-0 bg-black opacity-50" id="closeTambahModal"></div> <div class="absolute inset-0 bg-black opacity-50" id="closeTambahModal"></div>
<div class="bg-white rounded-lg shadow-lg w-full max-w-md z-50 overflow-hidden"> <div class="bg-white rounded-lg shadow-lg w-full max-w-md z-50 flex flex-col max-h-[90vh]">
<form action="{{ route('templates.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="p-4 border-b">
<h5 class="text-lg font-medium">Tambah Template</h5>
</div>
<div class="p-4 space-y-4">
<div>
<label class="block text-sm font-medium">Nama Template</label>
<input type="text" name="nama_template" class="w-full p-2 border rounded" required
value="{{ old('nama_template') }}">
</div>
<div>
<label class="block text-sm font-medium">Kategori</label>
<select name="kategori_id" id="kategoriSelectTambah" class="w-full p-2 border rounded">
<option value="">-- Pilih Kategori --</option>
@foreach ($kategoris as $kategoriItem)
<option value="{{ $kategoriItem->id }}" @selected(old('kategori_id') == $kategoriItem->id)>
{{ $kategoriItem->nama }}
</option>
@endforeach
</select>
</div>
<!-- FITUR --> <!-- Header -->
<div> <div class="p-4 border-b sticky top-0 bg-white z-10">
<label class="block text-sm font-medium">Fitur</label> <h5 class="text-lg font-medium">Tambah Template</h5>
<div id="fiturContainerTambah" </div>
class="space-y-3 max-h-64 overflow-auto p-2 border rounded">
{{-- Fitur dengan kategori radio --}} <!-- Scrollable content -->
@foreach ($kategoriFiturs as $kategoriFitur) <div class="p-4 space-y-4 overflow-y-auto flex-1">
<div> <form action="{{ route('templates.store') }}" method="POST" enctype="multipart/form-data" class="h-full flex flex-col">
<p class="font-semibold text-gray-700 mb-1"> @csrf
{{ $kategoriFitur->deskripsi }} <div class="flex-1 space-y-4">
</p> <div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <label class="block text-sm font-medium">Nama Template</label>
@foreach ($fiturs->where('kategori_fitur_id', $kategoriFitur->id) as $fitur) <input type="text" name="nama_template" class="w-full p-2 border rounded" required
<label class="flex items-center space-x-2"> value="{{ old('nama_template') }}">
<input type="radio" name="fitur_id[{{ $kategoriFitur->id }}]" </div>
value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}" <div>
@checked(old("fitur_id.$kategoriFitur->id") == $fitur->id)> <label class="block text-sm font-medium">Kategori</label>
<span class="text-sm"> <select name="kategori_id" id="kategoriSelectTambah" class="w-full p-2 border rounded">
{{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }} <option value="">-- Pilih Kategori --</option>
(Rp {{ number_format($fitur->harga, 0, ',', '.') }}) @foreach ($kategoris as $kategoriItem)
</span> <option value="{{ $kategoriItem->id }}" @selected(old('kategori_id') == $kategoriItem->id)>
</label> {{ $kategoriItem->nama }}
@endforeach </option>
@endforeach
</select>
</div>
<!-- FITUR -->
<div>
<label class="block text-sm font-medium">Fitur</label>
<div id="fiturContainerTambah"
class="space-y-3 max-h-64 overflow-auto p-2 border rounded">
@foreach ($kategoriFiturs as $kategoriFitur)
<div>
<p class="font-semibold text-gray-700 mb-1">
{{ $kategoriFitur->deskripsi }}
</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
@foreach ($fiturs->where('kategori_fitur_id', $kategoriFitur->id) as $fitur)
<label class="flex items-center space-x-2">
<input type="radio" name="fitur_id[{{ $kategoriFitur->id }}]"
value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}"
@checked(old("fitur_id.$kategoriFitur->id") == $fitur->id)>
<span class="text-sm">
{{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }}
(Rp {{ number_format($fitur->harga, 0, ',', '.') }})
</span>
</label>
@endforeach
</div>
</div> </div>
</div> @endforeach
@endforeach
{{-- Fitur tanpa kategori checkbox --}} @if ($fitursTanpaKategori->count())
@if ($fitursTanpaKategori->count()) <div>
<div> <p class="font-semibold text-gray-700 mb-1">Fitur Lainnya</p>
<p class="font-semibold text-gray-700 mb-1">Fitur Lainnya</p> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> @foreach ($fitursTanpaKategori as $fitur)
@foreach ($fitursTanpaKategori as $fitur) <label class="flex items-center space-x-2">
<label class="flex items-center space-x-2"> <input type="checkbox" name="fitur_id[]"
<input type="checkbox" name="fitur_id[]" value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}"
value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}" {{ is_array(old('fitur_id')) && in_array($fitur->id, old('fitur_id')) ? 'checked' : '' }}>
{{ is_array(old('fitur_id')) && in_array($fitur->id, old('fitur_id')) ? 'checked' : '' }}> <span class="text-sm">
<span class="text-sm"> {{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }}
{{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }} (Rp {{ number_format($fitur->harga, 0, ',', '.') }})
(Rp {{ number_format($fitur->harga, 0, ',', '.') }}) </span>
</span> </label>
</label> @endforeach
@endforeach </div>
</div> </div>
</div> @endif
@endif </div>
</div>
<div>
<label class="block text-sm font-medium">Harga</label>
<input type="text" name="harga" class="w-full p-2 border rounded" required
min="0" value="{{ old('harga') }}">
</div>
<div>
<label class="block text-sm font-medium">Foto (opsional)</label>
<input type="file" name="foto" class="w-full p-2 border rounded" accept="image/*">
<small class="text-gray-500">Format: JPG, PNG, GIF. Maks 5MB.</small>
</div> </div>
</div> </div>
<div> <!-- Footer -->
<label class="block text-sm font-medium">Harga</label> <div class="p-4 border-t flex justify-end space-x-2 sticky bottom-0 bg-white z-10">
<input type="text" name="harga" class="w-full p-2 border rounded" required <button type="button" id="closeTambahBtn"
min="0" value="{{ old('harga') }}"> class="bg-gray-300 text-black px-3 py-1 rounded">Batal</button>
<button class="bg-blue-600 text-white px-3 py-1 rounded">Simpan</button>
</div> </div>
<div> </form>
<label class="block text-sm font-medium">Foto (opsional)</label> </div>
<input type="file" name="foto" class="w-full p-2 border rounded" accept="image/*">
<small class="text-gray-500">Format: JPG, PNG, GIF. Maks 5MB.</small>
</div>
</div>
<div class="p-4 border-t flex justify-end space-x-2">
<button type="button" id="closeTambahBtn"
class="bg-gray-300 text-black px-3 py-1 rounded">Batal</button>
<button class="bg-blue-600 text-white px-3 py-1 rounded">Simpan</button>
</div>
</form>
</div> </div>
</div> </div>
@endif @endif
@ -307,110 +226,115 @@
@foreach ($templates as $template) @foreach ($templates as $template)
<div id="modalEdit{{ $template->id }}" class="fixed inset-0 hidden items-center justify-center z-50"> <div id="modalEdit{{ $template->id }}" class="fixed inset-0 hidden items-center justify-center z-50">
<div class="absolute inset-0 bg-black opacity-50 closeEditOverlay" data-id="{{ $template->id }}"></div> <div class="absolute inset-0 bg-black opacity-50 closeEditOverlay" data-id="{{ $template->id }}"></div>
<div class="bg-white rounded-lg shadow-lg w-full max-w-md z-50 overflow-hidden"> <div class="bg-white rounded-lg shadow-lg w-full max-w-md z-50 flex flex-col max-h-[90vh]">
<form action="{{ route('templates.update', $template->id) }}" method="POST"
enctype="multipart/form-data">
@csrf @method('PUT')
<div class="p-4 border-b">
<h5 class="text-lg font-medium">Edit Template</h5>
</div>
<div class="p-4 space-y-4">
<div>
<label class="block text-sm font-medium">Nama Template</label>
<input type="text" name="nama_template"
value="{{ old('nama_template', $template->nama_template) }}"
class="w-full p-2 border rounded" required>
</div>
<div>
<label class="block text-sm font-medium">Kategori</label>
<select name="kategori_id" id="kategoriSelectEdit{{ $template->id }}"
class="w-full p-2 border rounded">
<option value="">-- Pilih Kategori --</option>
@foreach ($kategoris as $kategoriItem)
<option value="{{ $kategoriItem->id }}" @selected($kategoriItem->id == old('kategori_id', $template->kategori_id))>
{{ $kategoriItem->nama }}
</option>
@endforeach
</select>
</div>
<!-- FITUR --> <!-- Header -->
<div> <div class="p-4 border-b sticky top-0 bg-white z-10">
<label class="block text-sm font-medium">Fitur</label> <h5 class="text-lg font-medium">Edit Template</h5>
<div id="fiturContainerEdit{{ $template->id }}" </div>
class="space-y-3 max-h-64 overflow-auto p-2 border rounded">
{{-- Fitur dengan kategori radio --}} <!-- Scrollable content -->
@foreach ($kategoriFiturs as $kategoriFitur) <div class="p-4 space-y-4 overflow-y-auto flex-1">
<div> <form action="{{ route('templates.update', $template->id) }}" method="POST"
<p class="font-semibold text-gray-700 mb-1"> enctype="multipart/form-data" class="h-full flex flex-col">
{{ $kategoriFitur->deskripsi }} @csrf @method('PUT')
</p> <div class="flex-1 space-y-4">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div>
@foreach ($fiturs->where('kategori_fitur_id', $kategoriFitur->id) as $fiturItem) <label class="block text-sm font-medium">Nama Template</label>
<label class="flex items-center space-x-2"> <input type="text" name="nama_template"
<input type="radio" name="fitur_id[{{ $kategoriFitur->id }}]" value="{{ old('nama_template', $template->nama_template) }}"
value="{{ $fiturItem->id }}" class="w-full p-2 border rounded" required>
data-harga="{{ $fiturItem->harga }}" </div>
{{ old("fitur_id.$kategoriFitur->id") == $fiturItem->id || $template->fiturs->contains($fiturItem->id) ? 'checked' : '' }}> <div>
<span class="text-sm"> <label class="block text-sm font-medium">Kategori</label>
{{ \Illuminate\Support\Str::limit($fiturItem->deskripsi, 80) }} <select name="kategori_id" id="kategoriSelectEdit{{ $template->id }}"
(Rp {{ number_format($fiturItem->harga, 0, ',', '.') }}) class="w-full p-2 border rounded">
</span> <option value="">-- Pilih Kategori --</option>
</label> @foreach ($kategoris as $kategoriItem)
@endforeach <option value="{{ $kategoriItem->id }}" @selected($kategoriItem->id == old('kategori_id', $template->kategori_id))>
{{ $kategoriItem->nama }}
</option>
@endforeach
</select>
</div>
<!-- FITUR -->
<div>
<label class="block text-sm font-medium">Fitur</label>
<div id="fiturContainerEdit{{ $template->id }}"
class="space-y-3 max-h-64 overflow-auto p-2 border rounded">
@foreach ($kategoriFiturs as $kategoriFitur)
<div>
<p class="font-semibold text-gray-700 mb-1">
{{ $kategoriFitur->deskripsi }}
</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
@foreach ($fiturs->where('kategori_fitur_id', $kategoriFitur->id) as $fiturItem)
<label class="flex items-center space-x-2">
<input type="radio" name="fitur_id[{{ $kategoriFitur->id }}]"
value="{{ $fiturItem->id }}"
data-harga="{{ $fiturItem->harga }}"
{{ old("fitur_id.$kategoriFitur->id") == $fiturItem->id || $template->fiturs->contains($fiturItem->id) ? 'checked' : '' }}>
<span class="text-sm">
{{ \Illuminate\Support\Str::limit($fiturItem->deskripsi, 80) }}
(Rp {{ number_format($fiturItem->harga, 0, ',', '.') }})
</span>
</label>
@endforeach
</div>
</div> </div>
</div> @endforeach
@endforeach
{{-- Fitur tanpa kategori checkbox --}} @if ($fitursTanpaKategori->count())
@if ($fitursTanpaKategori->count()) <div>
<div> <p class="font-semibold text-gray-700 mb-1">Fitur Lainnya</p>
<p class="font-semibold text-gray-700 mb-1">Fitur Lainnya</p> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> @foreach ($fitursTanpaKategori as $fitur)
@foreach ($fitursTanpaKategori as $fitur) <label class="flex items-center space-x-2">
<label class="flex items-center space-x-2"> <input type="checkbox" name="fitur_id[]"
<input type="checkbox" name="fitur_id[]" value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}"
value="{{ $fitur->id }}" data-harga="{{ $fitur->harga }}" {{ (is_array(old('fitur_id')) && in_array($fitur->id, old('fitur_id'))) || $template->fiturs->contains($fitur->id) ? 'checked' : '' }}>
{{ (is_array(old('fitur_id')) && in_array($fitur->id, old('fitur_id'))) || $template->fiturs->contains($fitur->id) ? 'checked' : '' }}> <span class="text-sm">
<span class="text-sm"> {{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }}
{{ \Illuminate\Support\Str::limit($fitur->deskripsi, 80) }} (Rp {{ number_format($fitur->harga, 0, ',', '.') }})
(Rp {{ number_format($fitur->harga, 0, ',', '.') }}) </span>
</span> </label>
</label> @endforeach
@endforeach </div>
</div>
@endif
</div>
</div>
<div>
<label class="block text-sm font-medium">Harga</label>
<input type="text" name="harga" value="{{ old('harga', $template->harga) }}"
class="w-full p-2 border rounded" required min="0">
</div>
<div>
<label class="block text-sm font-medium">Foto (opsional)</label>
@if ($template->foto)
<div class="mb-2">
<small class="text-gray-500">Foto saat ini:</small>
<div
class="w-20 h-20 mt-1 overflow-hidden rounded bg-gray-100 flex items-center justify-center border">
<img src="{{ asset('storage/' . $template->foto) }}" alt="foto"
class="max-w-full max-h-full object-contain">
</div> </div>
</div> </div>
@endif @endif
<input type="file" name="foto" class="w-full p-2 border rounded" accept="image/*">
</div> </div>
</div> </div>
<div> <!-- Footer -->
<label class="block text-sm font-medium">Harga</label> <div class="p-4 border-t flex justify-end space-x-2 sticky bottom-0 bg-white z-10">
<input type="text" name="harga" value="{{ old('harga', $template->harga) }}" <button type="button" class="bg-gray-300 text-black px-3 py-1 rounded closeEditBtn"
class="w-full p-2 border rounded" required min="0"> data-id="{{ $template->id }}">Batal</button>
<button class="bg-blue-600 text-white px-3 py-1 rounded">Simpan Perubahan</button>
</div> </div>
<div> </form>
<label class="block text-sm font-medium">Foto (opsional)</label> </div>
@if ($template->foto)
<div class="mb-2">
<small class="text-gray-500">Foto saat ini:</small>
<div
class="w-20 h-20 mt-1 overflow-hidden rounded bg-gray-100 flex items-center justify-center border">
<img src="{{ asset('storage/' . $template->foto) }}" alt="foto"
class="max-w-full max-h-full object-contain">
</div>
</div>
@endif
<input type="file" name="foto" class="w-full p-2 border rounded" accept="image/*">
</div>
</div>
<div class="p-4 border-t flex justify-end space-x-2">
<button type="button" class="bg-gray-300 text-black px-3 py-1 rounded closeEditBtn"
data-id="{{ $template->id }}">Batal</button>
<button class="bg-blue-600 text-white px-3 py-1 rounded">Simpan Perubahan</button>
</div>
</form>
</div> </div>
</div> </div>
@endforeach @endforeach