445 lines
24 KiB
PHP
445 lines
24 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('title', 'Tambah Paket - INUFA')
|
|
|
|
@section('header', 'Tambah Paket Baru')
|
|
|
|
@section('content')
|
|
<div class="container mx-auto px-4 py-6">
|
|
<div class="bg-white rounded-lg shadow-md p-6 max-w-4xl mx-auto">
|
|
<form action="{{ route('paket.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
|
@csrf
|
|
|
|
<!-- Informasi Paket -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<div>
|
|
<h3 class="text-lg font-semibold mb-4 text-gray-800">Informasi Paket</h3>
|
|
|
|
<!-- Nama Paket -->
|
|
<div class="mb-4">
|
|
<label for="nama_paket" class="block text-gray-700 font-medium mb-2">Nama Paket <span class="text-red-500">*</span></label>
|
|
<input type="text" id="nama_paket" name="nama_paket" value="{{ old('nama_paket') }}" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Contoh: Paket Sound System Wedding" required>
|
|
@error('nama_paket')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Jenis Paket -->
|
|
<div class="mb-4">
|
|
<label for="jenis_paket" class="block text-gray-700 font-medium mb-2">Jenis Paket <span class="text-red-500">*</span></label>
|
|
<select id="jenis_paket" name="jenis_paket" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" required>
|
|
<option value="">Pilih Jenis Paket</option>
|
|
<option value="wedding" {{ old('jenis_paket') == 'wedding' ? 'selected' : '' }}>Wedding</option>
|
|
<option value="seminar" {{ old('jenis_paket') == 'seminar' ? 'selected' : '' }}>Seminar/Meeting</option>
|
|
<option value="outdoor" {{ old('jenis_paket') == 'outdoor' ? 'selected' : '' }}>Outdoor/Karnaval</option>
|
|
<option value="custom" {{ old('jenis_paket') == 'custom' ? 'selected' : '' }}>Custom</option>
|
|
</select>
|
|
@error('jenis_paket')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Harga Sewa -->
|
|
<div class="mb-4">
|
|
<label for="harga" class="block text-gray-700 font-medium mb-2">Harga Sewa (Rp) <span class="text-red-500">*</span></label>
|
|
<div class="relative">
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
<span class="text-gray-500">Rp</span>
|
|
</div>
|
|
<input type="number" id="harga" name="harga" value="{{ old('harga') }}" class="w-full border border-gray-300 rounded-md pl-10 pr-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Contoh: 5000000" required>
|
|
</div>
|
|
<p class="text-xs text-gray-500 mt-1">Harga per hari untuk sewa paket ini</p>
|
|
@error('harga')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Ongkir per KM -->
|
|
<!-- <div class="mb-4">
|
|
<label for="ongkir_km" class="block text-gray-700 font-medium mb-2">Ongkir per KM (Rp)</label>
|
|
<div class="relative">
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
<span class="text-gray-500">Rp</span>
|
|
</div>
|
|
<input type="number" id="ongkir_km" name="ongkir_km" value="{{ old('ongkir_km', 5000) }}" class="w-full border border-gray-300 rounded-md pl-10 pr-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Contoh: 5000">
|
|
</div>
|
|
<p class="text-xs text-gray-500 mt-1">Biaya pengiriman per kilometer (kosongkan jika tidak ada)</p>
|
|
@error('ongkir_km')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div> -->
|
|
|
|
<!-- Minimal Jarak Ongkir -->
|
|
<!-- <div class="mb-4">
|
|
<label for="min_jarak" class="block text-gray-700 font-medium mb-2">Minimal Jarak Ongkir (KM)</label>
|
|
<input type="number" id="min_jarak" name="min_jarak" value="{{ old('min_jarak', 0) }}" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Contoh: 5">
|
|
<p class="text-xs text-gray-500 mt-1">Jarak minimal sebelum dikenakan ongkir (0 untuk tidak ada minimum)</p>
|
|
@error('min_jarak')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div> -->
|
|
|
|
<!-- Stok -->
|
|
<div class="mb-4">
|
|
<label for="stok" class="block text-gray-700 font-medium mb-2">Stok Paket <span class="text-red-500">*</span></label>
|
|
<input type="number" id="stok" name="stok" value="{{ old('stok', 1) }}" min="1" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" required>
|
|
<p class="text-xs text-gray-500 mt-1">Jumlah paket yang tersedia untuk disewa</p>
|
|
@error('stok')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<!-- Ongkir per Kota -->
|
|
<div class="mb-4">
|
|
<label class="block text-gray-700 font-medium mb-2">Ongkir per Kabupaten</label>
|
|
<div id="ongkir-container">
|
|
<div class="ongkir-form mb-2 p-4 border rounded-lg bg-gray-50">
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-600">Nama Kabupaten</label>
|
|
<input type="text" name="ongkir[0][nama_kota]" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-600">Biaya Ongkir (Rp)</label>
|
|
<input type="number" name="ongkir[0][biaya_ongkir]" min="0" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
</div>
|
|
</div>
|
|
<button type="button" class="mt-2 text-red-600 hover:text-red-800 delete-ongkir" style="display: none;">
|
|
<i class="fas fa-trash mr-1"></i> Hapus
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<button type="button" id="tambah-ongkir" class="mt-2 text-sm bg-green-500 hover:bg-green-600 text-white px-3 py-1 rounded">
|
|
<i class="fas fa-plus mr-1"></i> Tambah Kabupaten
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<!-- Gambar Paket -->
|
|
<div class="mb-6">
|
|
<h3 class="text-lg font-semibold mb-4 text-gray-800">Gambar Paket</h3>
|
|
<div class="mb-4">
|
|
<label for="image" class="block text-gray-700 font-medium mb-2">Upload Gambar</label>
|
|
<div class="mt-1 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md relative"
|
|
id="drop-zone">
|
|
<div class="space-y-1 text-center">
|
|
<img id="preview-image" src="#" alt="Preview" class="mx-auto h-32 w-auto hidden" style="display: none;">
|
|
<svg id="preview-placeholder" class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48">
|
|
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
<div class="flex text-sm text-gray-600 justify-center">
|
|
<label for="image" class="relative cursor-pointer bg-white rounded-md font-medium text-blue-600 hover:text-blue-500 focus-within:outline-none">
|
|
<span>Upload gambar</span>
|
|
<input id="image" name="image" type="file" class="sr-only" accept="image/*">
|
|
</label>
|
|
<p class="pl-1">atau drag and drop</p>
|
|
</div>
|
|
<p class="text-xs text-gray-500">PNG, JPG, GIF sampai 10MB</p>
|
|
</div>
|
|
</div>
|
|
@error('image')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Deskripsi Paket -->
|
|
<div class="mb-4">
|
|
<label for="keterangan" class="block text-gray-700 font-medium mb-2">Deskripsi Paket</label>
|
|
<textarea id="keterangan" name="keterangan" rows="5" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Deskripsi lengkap tentang paket ini...">{{ old('keterangan') }}</textarea>
|
|
@error('keterangan')
|
|
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pilihan Barang Paket -->
|
|
<div class="mt-6">
|
|
<h3 class="text-lg font-semibold mb-4 text-gray-800">Pilih Barang untuk Paket</h3>
|
|
<p class="text-sm text-gray-600 mb-4">Pilih barang yang akan dimasukkan ke dalam paket</p>
|
|
|
|
@if($barangs->isEmpty())
|
|
<div class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-4">
|
|
<div class="flex">
|
|
<div class="flex-shrink-0">
|
|
<svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor">
|
|
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
|
|
</svg>
|
|
</div>
|
|
<div class="ml-3">
|
|
<p class="text-sm text-yellow-700">
|
|
Tidak ada barang yang tersedia saat ini.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<div class="overflow-x-auto bg-white rounded-lg shadow">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Pilih</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Nama Barang</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Detail Barang</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Stok Tersedia</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Jumlah</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
@foreach($barangs as $barang)
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<input type="checkbox"
|
|
name="barang_ids[]"
|
|
value="{{ $barang->id }}"
|
|
class="barang-checkbox focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-300 rounded"
|
|
data-barang-id="{{ $barang->id }}">
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div class="text-sm font-medium text-gray-900">{{ $barang->nama_barang }}</div>
|
|
<div class="text-xs text-gray-500">Kode: {{ $barang->kode_barang }}</div>
|
|
</td>
|
|
<td class="px-6 py-4">
|
|
<div class="text-sm text-gray-900">
|
|
<div class="mb-1"><span class="font-medium">Kategori:</span> {{ $barang->kategori }}</div>
|
|
<div class="text-xs text-gray-500">{{ $barang->deskripsi }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">
|
|
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $barang->stok > 0 ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800' }}">
|
|
{{ $barang->stok }} unit
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<input type="number"
|
|
name="jumlah_{{ $barang->id }}"
|
|
id="jumlah_{{ $barang->id }}"
|
|
min="1"
|
|
max="{{ $barang->stok }}"
|
|
value="1"
|
|
class="border border-gray-300 rounded-md px-3 py-2 w-24 focus:outline-none focus:ring-2 focus:ring-blue-500 text-center"
|
|
data-max-stok="{{ $barang->stok }}"
|
|
data-barang-id="{{ $barang->id }}">
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Tombol Submit dan Batal -->
|
|
<div class="flex justify-end space-x-4 pt-6 border-t">
|
|
<a href="{{ route('paket.index') }}" class="px-4 py-2 bg-gray-300 text-gray-800 rounded-md hover:bg-gray-400 transition duration-300">
|
|
Batal
|
|
</a>
|
|
<button type="submit" class="px-6 py-2 bg-blue-700 text-white rounded-md hover:bg-blue-800 transition duration-300">
|
|
Simpan Paket
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
// Tunggu sampai DOM selesai dimuat
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('DOM Content Loaded');
|
|
|
|
// Ambil referensi elemen-elemen yang dibutuhkan
|
|
const fileInput = document.getElementById('image');
|
|
const previewImage = document.getElementById('preview-image');
|
|
const previewPlaceholder = document.getElementById('preview-placeholder');
|
|
const dropZone = document.getElementById('drop-zone');
|
|
|
|
// Log status elemen
|
|
console.log('Elements found:', {
|
|
fileInput: !!fileInput,
|
|
previewImage: !!previewImage,
|
|
previewPlaceholder: !!previewPlaceholder,
|
|
dropZone: !!dropZone
|
|
});
|
|
|
|
// Fungsi untuk menangani preview file
|
|
function handleFileSelect(file) {
|
|
console.log('Handling file:', file);
|
|
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = function(e) {
|
|
console.log('File loaded');
|
|
if (previewImage && previewPlaceholder) {
|
|
previewImage.src = e.target.result;
|
|
previewImage.style.display = 'block';
|
|
previewImage.classList.remove('hidden');
|
|
previewPlaceholder.classList.add('hidden');
|
|
console.log('Preview updated');
|
|
}
|
|
};
|
|
|
|
reader.onerror = function(error) {
|
|
console.error('Error reading file:', error);
|
|
};
|
|
|
|
reader.readAsDataURL(file);
|
|
}
|
|
}
|
|
|
|
// Event listener untuk file input
|
|
if (fileInput) {
|
|
fileInput.addEventListener('change', function(e) {
|
|
console.log('File input change event');
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
handleFileSelect(file);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Event listeners untuk drag & drop
|
|
if (dropZone) {
|
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
|
dropZone.addEventListener(eventName, function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
console.log(eventName + ' event handled');
|
|
});
|
|
});
|
|
|
|
// Styling saat drag
|
|
dropZone.addEventListener('dragenter', function(e) {
|
|
console.log('Drag enter');
|
|
this.classList.add('border-blue-500', 'bg-blue-50');
|
|
});
|
|
|
|
dropZone.addEventListener('dragover', function(e) {
|
|
console.log('Drag over');
|
|
this.classList.add('border-blue-500', 'bg-blue-50');
|
|
});
|
|
|
|
dropZone.addEventListener('dragleave', function(e) {
|
|
console.log('Drag leave');
|
|
this.classList.remove('border-blue-500', 'bg-blue-50');
|
|
});
|
|
|
|
// Handle file drop
|
|
dropZone.addEventListener('drop', function(e) {
|
|
console.log('File dropped');
|
|
this.classList.remove('border-blue-500', 'bg-blue-50');
|
|
|
|
const file = e.dataTransfer.files[0];
|
|
if (file) {
|
|
fileInput.files = e.dataTransfer.files;
|
|
handleFileSelect(file);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Fungsi untuk mengaktifkan input saat checkbox dicentang
|
|
function toggleInput(checkbox) {
|
|
const barangId = checkbox.dataset.barangId;
|
|
const input = document.getElementById('jumlah_' + barangId);
|
|
if (input) {
|
|
input.disabled = !checkbox.checked;
|
|
if (!checkbox.checked) {
|
|
input.value = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Event listener untuk checkbox
|
|
document.querySelectorAll('.barang-checkbox').forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
toggleInput(this);
|
|
});
|
|
});
|
|
|
|
// Event listener untuk input jumlah
|
|
document.querySelectorAll('input[name^="jumlah_"]').forEach(input => {
|
|
// Nonaktifkan input saat awal
|
|
input.disabled = true;
|
|
|
|
// Validasi saat input berubah
|
|
input.addEventListener('input', function() {
|
|
const maxStok = parseInt(this.dataset.maxStok);
|
|
let value = parseInt(this.value);
|
|
|
|
// Jika input kosong, biarkan
|
|
if (this.value === '') return;
|
|
|
|
// Jika nilai lebih dari stok maksimum
|
|
if (value > maxStok) {
|
|
this.value = maxStok;
|
|
alert('Jumlah tidak boleh melebihi stok tersedia (' + maxStok + ' unit)');
|
|
}
|
|
|
|
// Jika nilai kurang dari 1
|
|
if (value < 1) {
|
|
this.value = 1;
|
|
}
|
|
});
|
|
});
|
|
|
|
// Ongkir dynamic form
|
|
const ongkirContainer = document.getElementById('ongkir-container');
|
|
const tambahOngkirBtn = document.getElementById('tambah-ongkir');
|
|
let ongkirCount = 1;
|
|
|
|
// Fungsi untuk menambah form ongkir baru
|
|
tambahOngkirBtn.addEventListener('click', function() {
|
|
const template = ongkirContainer.children[0].cloneNode(true);
|
|
|
|
// Update nama field
|
|
const inputs = template.querySelectorAll('input');
|
|
inputs.forEach(input => {
|
|
input.name = input.name.replace('[0]', `[${ongkirCount}]`);
|
|
input.value = '';
|
|
});
|
|
|
|
// Tampilkan tombol hapus
|
|
const deleteBtn = template.querySelector('.delete-ongkir');
|
|
deleteBtn.style.display = 'inline-flex';
|
|
|
|
// Tambahkan event listener untuk tombol hapus
|
|
deleteBtn.addEventListener('click', function() {
|
|
template.remove();
|
|
updateDeleteButtons();
|
|
});
|
|
|
|
ongkirContainer.appendChild(template);
|
|
ongkirCount++;
|
|
updateDeleteButtons();
|
|
});
|
|
|
|
// Tampilkan/sembunyikan tombol hapus
|
|
const updateDeleteButtons = () => {
|
|
const forms = ongkirContainer.children;
|
|
const deleteButtons = ongkirContainer.querySelectorAll('.delete-ongkir');
|
|
|
|
deleteButtons.forEach((btn, index) => {
|
|
if (forms.length > 1) {
|
|
btn.style.display = 'inline-flex';
|
|
} else {
|
|
btn.style.display = 'none';
|
|
}
|
|
});
|
|
};
|
|
|
|
// Event delegation untuk tombol hapus
|
|
ongkirContainer.addEventListener('click', function(e) {
|
|
if (e.target.classList.contains('delete-ongkir')) {
|
|
e.target.closest('.ongkir-form').remove();
|
|
updateDeleteButtons();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endpush |