'required|string|max:255|unique:bundles,name', 'description' => 'nullable|string', 'price' => 'nullable|numeric|min:0', 'is_active' => 'boolean', 'selectedItems' => 'nullable|array', // selectedItems sekarang adalah array 'selectedItems.*' => 'exists:items,id', // Setiap ID dalam array harus ada di tabel items ]; // Mounted lifecycle hook untuk mengambil data dropdown public function mount() { $this->allItems = Items::all(['id', 'name']); // Ambil semua item untuk pilihan di form } // Reset halaman pagination setiap kali properti pencarian berubah public function updatingSearch() { $this->resetPage(); } // Metode untuk mengubah kolom sorting public function sortBy($field) { if ($this->sortBy === $field) { $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc'; } else { $this->sortBy = $field; $this->sortDirection = 'asc'; } } // Metode untuk membuka modal Create Bundle public function create() { $this->resetInputFields(); $this->is_active = true; // Tidak perlu mengambil allItems lagi karena sudah di mount(), // tapi pastikan selectedItems direset $this->selectedItems = []; $this->isModalOpen = true; } // Metode untuk mengisi form edit dan membuka modal public function edit($id) { $bundle = Bundles::findOrFail($id); // Gunakan Bundle $this->bundleId = $bundle->id; $this->name = $bundle->name; $this->description = $bundle->description; $this->price = $bundle->price; $this->is_active = $bundle->is_active; // === PENTING: Ambil ID item yang sudah terkait dengan bundle ini === $this->selectedItems = $bundle->items->pluck('id')->toArray(); $this->isModalOpen = true; } // Metode untuk menyimpan atau memperbarui Bundle public function store() { $rules = $this->rules; if ($this->bundleId) { // Untuk update, 'name' harus unique kecuali jika itu adalah nama dari bundle yang sedang diedit $rules['name'] = 'required|string|max:255|unique:bundles,name,' . $this->bundleId; } $this->validate($rules); $bundleData = [ 'name' => $this->name, 'description' => $this->description, 'price' => $this->price, 'is_active' => $this->is_active, ]; $bundle = null; // Inisialisasi variabel $bundle if ($this->bundleId) { // Update Bundle $bundle = Bundles::find($this->bundleId); // Gunakan Bundle $bundle->update($bundleData); session()->flash('message', 'Bundle berhasil diperbarui!'); } else { // Create Bundle $bundle = Bundles::create($bundleData); // Gunakan Bundle session()->flash('message', 'Bundle berhasil ditambahkan!'); } // === PENTING: Sinkronkan relasi many-to-many setelah bundle dibuat/diperbarui === if ($bundle && !empty($this->selectedItems)) { $bundle->items()->sync($this->selectedItems); } elseif ($bundle) { // Jika tidak ada item yang dipilih, detach semua relasi item yang ada $bundle->items()->detach(); } $this->closeModal(); $this->resetInputFields(); } // Metode untuk membuka modal konfirmasi hapus public function confirmDelete($id) { $this->bundleToDeleteId = $id; $this->isDeleteModalOpen = true; } // Metode untuk menghapus Bundle public function delete() { if ($this->bundleToDeleteId) { $bundle = Bundles::find($this->bundleToDeleteId); // Gunakan Bundle if ($bundle) { // Relasi many-to-many secara otomatis akan di-cascade oleh foreign key ON DELETE CASCADE // di tabel pivot (bundle_item) ketika bundle dihapus. // Oleh karena itu, $bundle->items()->detach(); sebenarnya tidak mutlak diperlukan di sini // jika DB constraint sudah diatur dengan benar. // Namun, secara eksplisit detach juga aman dilakukan. // $bundle->items()->detach(); $bundle->delete(); session()->flash('message', 'Bundle berhasil dihapus!'); } } $this->closeDeleteModal(); } // Tutup modal create/edit public function closeModal() { $this->isModalOpen = false; $this->resetValidation(); } // Tutup modal konfirmasi hapus public function closeDeleteModal() { $this->isDeleteModalOpen = false; $this->bundleToDeleteId = null; } // Reset semua input form private function resetInputFields() { $this->bundleId = null; $this->name = ''; $this->description = ''; $this->price = ''; $this->is_active = true; $this->selectedItems = []; // Reset selectedItems ke array kosong } // Metode render komponen Livewire public function render() { $bundles = Bundles::query() // Gunakan Bundle ->when($this->search, function ($query) { $query->where('name', 'like', '%' . $this->search . '%') ->orWhere('description', 'like', '%' . $this->search . '%'); }) ->orderBy($this->sortBy, $this->sortDirection) // === EAGER LOAD RELASI ITEMS UNTUK MENAMPILKANNYA DI VIEW === ->with('items') // Eager load relasi items untuk menampilkan di tabel ->paginate(10); return view('livewire.bundle-table', [ 'bundles' => $bundles, // allItems akan tersedia secara otomatis karena public property ]); } }