289 lines
14 KiB
PHP
289 lines
14 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Laporan Admin</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
|
|
<style>
|
|
.fade-in {
|
|
opacity: 0;
|
|
transform: translateY(10px);
|
|
transition: all 0.4s ease-in-out;
|
|
}
|
|
.fade-in.opacity-100 {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-100 text-gray-900 font-[Inter]">
|
|
|
|
<!-- Sidebar -->
|
|
<div id="sidebar" class="fixed top-0 left-0 w-64 bg-white shadow-md z-30 h-screen overflow-y-auto hidden md:block">
|
|
<div class="p-5 border-b">
|
|
<h2 class="text-2xl font-bold text-blue-600">
|
|
<a href="/admin/dashboard" class="hover:underline">Admin Panel</a>
|
|
</h2>
|
|
</div>
|
|
<nav class="p-4 space-y-3">
|
|
<a href="/admin/bookings" class="flex items-center gap-3 px-4 py-2 rounded hover:bg-blue-100">
|
|
<i class="bi bi-calendar3 text-blue-500"></i> Booking
|
|
</a>
|
|
<a href="/admin/users" class="flex items-center gap-3 px-4 py-2 rounded hover:bg-blue-100">
|
|
<i class="bi bi-people-fill text-blue-500"></i> Pengguna
|
|
</a>
|
|
<a href="/admin/upload" class="flex items-center gap-3 px-4 py-2 rounded hover:bg-blue-100">
|
|
<i class="bi bi-upload text-blue-500"></i> Token Foto
|
|
</a>
|
|
<a href="/admin/reports" class="flex items-center gap-3 px-4 py-2 rounded bg-blue-100 text-blue-700">
|
|
<i class="bi bi-boxes text-blue-500"></i> Produk
|
|
</a>
|
|
<form action="/logout" method="POST" class="px-4 mt-4">
|
|
@csrf
|
|
<button type="submit" class="w-full flex items-center justify-center gap-2 bg-red-500 text-white py-2 rounded hover:bg-red-600">
|
|
<i class="bi bi-box-arrow-right"></i> Logout
|
|
</button>
|
|
</form>
|
|
</nav>
|
|
</div>
|
|
|
|
<!-- Mobile Top Bar -->
|
|
<div class="md:hidden fixed top-0 left-0 w-full bg-white shadow z-20 flex items-center justify-between px-4 py-3">
|
|
<button onclick="toggleSidebar()" class="text-2xl text-blue-600">
|
|
<i class="bi bi-list"></i>
|
|
</button>
|
|
<h1 class="text-xl font-bold text-blue-600">Admin Panel</h1>
|
|
</div>
|
|
|
|
<!-- Sidebar Overlay Mobile -->
|
|
<div id="overlay" class="fixed inset-0 bg-black bg-opacity-40 hidden z-10" onclick="toggleSidebar()"></div>
|
|
|
|
<!-- Main Content -->
|
|
<div class="md:ml-64 pt-20 md:pt-10 px-4 md:px-6 fade-in">
|
|
<h1 class="text-3xl font-bold mb-6">Tambah Produk Baru</h1>
|
|
|
|
@if(session('success'))
|
|
<div class="bg-green-100 text-green-800 p-3 rounded-lg mb-4">
|
|
{{ session('success') }}
|
|
</div>
|
|
@endif
|
|
|
|
<div class="bg-white p-6 rounded-lg shadow-md mb-10">
|
|
<form action="{{ route('admin.reports.store') }}" method="POST" enctype="multipart/form-data">
|
|
@csrf
|
|
<div class="grid md:grid-cols-3 gap-4">
|
|
<input type="text" name="kategori" placeholder="Kategori" class="border p-2 rounded-lg" value="{{ old('kategori') }}">
|
|
<input type="text" name="judul" placeholder="Judul Produk" class="border p-2 rounded-lg" value="{{ old('judul') }}">
|
|
<input type="text" name="deskripsi" placeholder="Deskripsi" class="border p-2 rounded-lg" value="{{ old('deskripsi') }}">
|
|
<input type="text" name="harga" placeholder="Harga Minimum" class="border p-2 rounded-lg rupiah" value="{{ old('harga') }}">
|
|
<input type="file" name="gambar" class="border p-2 rounded-lg md:col-span-2" accept="image/*">
|
|
</div>
|
|
|
|
<h2 class="text-xl font-bold mt-6">Pilihan Paket</h2>
|
|
@for($i = 0; $i < 3; $i++)
|
|
<div class="grid md:grid-cols-4 gap-4 mt-3">
|
|
<input type="text" name="paket[{{ $i }}][label]" class="border p-2 rounded-lg" placeholder="Label Paket (Opsional)" value="{{ old('paket.' . $i . '.label') }}">
|
|
<input type="text" name="paket[{{ $i }}][value]" class="border p-2 rounded-lg" placeholder="Value Paket" value="{{ old('paket.' . $i . '.value') }}">
|
|
<input type="text" name="paket[{{ $i }}][harga]" class="border p-2 rounded-lg rupiah" placeholder="Harga" value="{{ old('paket.' . $i . '.harga') }}">
|
|
<input type="text" name="paket[{{ $i }}][keterangan]" class="border p-2 rounded-lg" placeholder="Keterangan Paket (Opsional)" value="{{ old('paket.' . $i . '.keterangan') }}">
|
|
</div>
|
|
@endfor
|
|
|
|
<button type="submit" class="mt-4 bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 flex items-center">
|
|
<i class="bi bi-plus-lg mr-2"></i> Tambah Produk
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<h2 class="text-3xl font-bold mb-4">Daftar Produk</h2>
|
|
<div class="overflow-x-auto bg-white p-4 rounded-lg shadow">
|
|
<table class="min-w-full text-sm text-left">
|
|
<thead class="bg-blue-500 text-white">
|
|
<tr>
|
|
<th class="p-3">Gambar</th>
|
|
<th class="p-3">Kategori</th>
|
|
<th class="p-3">Judul</th>
|
|
<th class="p-3">Deskripsi</th>
|
|
<th class="p-3">Harga</th>
|
|
<th class="p-3">Paket</th>
|
|
<th class="p-3">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($pricelists as $item)
|
|
<tr class="border-b">
|
|
<td class="p-3"><img src="{{ asset('/' . $item->gambar) }}" class="w-16 h-16 object-cover rounded"></td>
|
|
<td class="p-3">{{ $item->kategori }}</td>
|
|
<td class="p-3">{{ $item->judul }}</td>
|
|
<td class="p-3">{{ $item->deskripsi }}</td>
|
|
<td class="p-3">Rp{{ number_format($item->harga, 0, ',', '.') }}</td>
|
|
<td class="p-3">
|
|
@php $paketList = is_string($item->paket) ? json_decode($item->paket, true) : $item->paket; @endphp
|
|
@if(is_array($paketList))
|
|
<ul class="list-disc ml-5">
|
|
@foreach($paketList as $paket)
|
|
<li>
|
|
{{ $paket['label'] ?? 'Paket' }} - Rp{{ number_format($paket['harga'] ?? 0, 0, ',', '.') }}
|
|
@if(!empty($paket['keterangan']))
|
|
<div class="text-xs text-gray-500 italic">({{ $paket['keterangan'] }})</div>
|
|
@endif
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
@else
|
|
<span class="text-gray-500">Tidak ada paket</span>
|
|
@endif
|
|
</td>
|
|
<td class="p-3 space-y-2">
|
|
<button onclick="openEditModal({{ $item }})" class="w-full bg-yellow-500 text-white py-1 rounded hover:bg-yellow-600"><i class="bi bi-pencil"></i> Edit</button>
|
|
<form action="{{ route('admin.reports.destroy', $item->id) }}" method="POST" onsubmit="return confirm('Hapus produk ini?')">
|
|
@csrf @method('DELETE')
|
|
<button class="w-full bg-red-500 text-white py-1 rounded hover:bg-red-600"><i class="bi bi-trash"></i> Hapus</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Edit -->
|
|
<div id="editModal" class="hidden fixed inset-0 z-50 bg-black bg-opacity-40 flex items-center justify-center">
|
|
<div class="bg-white p-6 rounded-lg shadow-lg w-[95%] md:w-1/2 max-h-[90vh] overflow-y-auto">
|
|
<h2 class="text-2xl font-bold mb-4">Edit Produk</h2>
|
|
<form id="editForm" method="POST" enctype="multipart/form-data">
|
|
@csrf @method('PUT')
|
|
<input type="hidden" id="editId" name="id">
|
|
<input type="text" id="editKategori" name="kategori" class="border p-2 rounded-lg w-full mb-3" placeholder="Kategori">
|
|
<input type="text" id="editJudul" name="judul" class="border p-2 rounded-lg w-full mb-3" placeholder="Judul Produk">
|
|
<textarea id="editDeskripsi" name="deskripsi" class="border p-2 rounded-lg w-full mb-3" placeholder="Deskripsi"></textarea>
|
|
<input type="text" id="editHarga" name="harga" class="rupiah border p-2 rounded-lg w-full mb-3" placeholder="Harga Minimum">
|
|
<input type="file" id="editGambar" name="gambar" class="border p-2 rounded-lg w-full mb-3" accept="image/*">
|
|
<h2 class="text-lg font-semibold mt-4">Paket</h2>
|
|
<div id="editPaketContainer"></div>
|
|
<button type="button" onclick="tambahPaketEdit()" class="mt-2 bg-green-500 text-white px-3 py-1 rounded-lg">Tambah Paket</button>
|
|
<div class="flex justify-end mt-4">
|
|
<button type="button" onclick="closeEditModal()" class="bg-gray-500 text-white px-4 py-2 rounded-lg mr-2">Batal</button>
|
|
<button type="submit" class="bg-blue-500 text-white px-4 py-2 rounded-lg">Simpan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function toggleSidebar() {
|
|
document.getElementById('sidebar').classList.toggle('hidden');
|
|
document.getElementById('overlay').classList.toggle('hidden');
|
|
}
|
|
|
|
function openEditModal(item) {
|
|
document.getElementById('editId').value = item.id;
|
|
document.getElementById('editKategori').value = item.kategori;
|
|
document.getElementById('editJudul').value = item.judul;
|
|
document.getElementById('editDeskripsi').value = item.deskripsi;
|
|
document.getElementById('editHarga').value = item.harga;
|
|
document.getElementById('editForm').action = `/admin/reports/${item.id}`;
|
|
|
|
let container = document.getElementById('editPaketContainer');
|
|
container.innerHTML = '';
|
|
let paketData = typeof item.paket === 'string' ? JSON.parse(item.paket) : item.paket;
|
|
|
|
if (Array.isArray(paketData)) {
|
|
paketData.forEach((paket, index) => tambahPaketEdit(paket, index));
|
|
} else {
|
|
tambahPaketEdit();
|
|
}
|
|
|
|
document.getElementById('editModal').classList.remove('hidden');
|
|
}
|
|
|
|
function closeEditModal() {
|
|
document.getElementById('editModal').classList.add('hidden');
|
|
}
|
|
|
|
function tambahPaketEdit(paket = {}, index = null) {
|
|
let container = document.getElementById('editPaketContainer');
|
|
let id = index !== null ? index : document.querySelectorAll('.paket-edit').length;
|
|
|
|
let div = document.createElement('div');
|
|
div.className = 'grid md:grid-cols-4 gap-4 mt-3 paket-edit';
|
|
div.innerHTML = `
|
|
<input type="text" name="paket[${id}][label]" class="border p-2 rounded-lg" placeholder="Label" value="${paket.label || ''}">
|
|
<input type="text" name="paket[${id}][value]" class="border p-2 rounded-lg" placeholder="Value" value="${paket.value || ''}">
|
|
<input type="text" name="paket[${id}][harga]" class="rupiah border p-2 rounded-lg" placeholder="Harga" value="${paket.harga || ''}">
|
|
<input type="text" name="paket[${id}][keterangan]" class="border p-2 rounded-lg" placeholder="Keterangan" value="${paket.keterangan || ''}">
|
|
`;
|
|
container.appendChild(div);
|
|
|
|
// Apply formatting to the new input
|
|
let hargaInput = div.querySelector('.rupiah');
|
|
if (hargaInput) {
|
|
formatRupiahInput(hargaInput);
|
|
}
|
|
}
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
setTimeout(() => {
|
|
document.querySelectorAll('.fade-in').forEach(el => {
|
|
el.classList.add('opacity-100', 'translate-y-0');
|
|
});
|
|
}, 200);
|
|
});
|
|
</script>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const rupiahInputs = document.querySelectorAll('.rupiah');
|
|
|
|
rupiahInputs.forEach(input => {
|
|
input.addEventListener('input', function (e) {
|
|
let value = this.value.replace(/[^\d]/g, '');
|
|
value = new Intl.NumberFormat('id-ID', {
|
|
style: 'currency',
|
|
currency: 'IDR',
|
|
minimumFractionDigits: 0
|
|
}).format(value);
|
|
this.value = value.replace('Rp', 'Rp ');
|
|
});
|
|
|
|
// Optional: clean format before submit
|
|
input.form?.addEventListener('submit', function () {
|
|
rupiahInputs.forEach(el => {
|
|
el.value = el.value.replace(/[^0-9]/g, '');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
<script>
|
|
function formatRupiahInput(input) {
|
|
input.addEventListener('input', function () {
|
|
let value = this.value.replace(/[^\d]/g, '');
|
|
value = new Intl.NumberFormat('id-ID', {
|
|
style: 'currency',
|
|
currency: 'IDR',
|
|
minimumFractionDigits: 0
|
|
}).format(value);
|
|
this.value = value.replace('Rp', 'Rp ');
|
|
});
|
|
|
|
// Optional: clean value on submit
|
|
input.form?.addEventListener('submit', function () {
|
|
input.value = input.value.replace(/[^0-9]/g, '');
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Apply to static elements
|
|
document.querySelectorAll('.rupiah').forEach(formatRupiahInput);
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|