diff --git a/backend/app/Http/Controllers/TemplateController.php b/backend/app/Http/Controllers/TemplateController.php index 272c19b..16f51e2 100644 --- a/backend/app/Http/Controllers/TemplateController.php +++ b/backend/app/Http/Controllers/TemplateController.php @@ -13,83 +13,88 @@ class TemplateController extends Controller public function index() { // eager load fiturs & kategori - $templates = Template::with(['kategori', 'fiturs']) - ->paginate(5); // <= pagination 10 item per halaman + $templates = Template::with(['kategori', 'fiturs'])->paginate(5); $kategoris = Kategori::all(); $fiturs = Fitur::all(); return view('admin.templates.index', compact('templates', 'kategoris', 'fiturs')); } -public function show($id) -{ - return Template::with('kategori')->findOrFail($id); -} - - -public function store(Request $request) -{ - $data = $request->validate([ - 'nama_template' => 'required|string|max:255', - 'kategori_id' => 'required|exists:kategoris,id', - 'fitur_id' => 'required|array', - 'fitur_id.*' => 'exists:fiturs,id', - 'foto' => 'nullable|image|mimes:jpg,jpeg,png,gif|max:5120', - ]); - - // hitung total harga dari fitur yang dipilih - $totalHarga = Fitur::whereIn('id', $data['fitur_id'])->sum('harga'); - - if ($request->hasFile('foto')) { - $data['foto'] = $request->file('foto')->store('templates', 'public'); + public function show($id) + { + return Template::with('kategori')->findOrFail($id); } -// store -$template = Template::create([ - 'nama_template' => $data['nama_template'], - 'kategori_id' => $data['kategori_id'], - 'foto' => $data['foto'] ?? null, - 'harga' => $request->harga, // ✅ ambil langsung dari input -]); + public function store(Request $request) + { + $data = $request->validate([ + 'nama_template' => 'required|string|max:255', + 'kategori_id' => 'required|exists:kategoris,id', + 'fitur_id' => 'required|array', + 'fitur_id.*' => 'exists:fiturs,id', + 'foto' => 'nullable|image|mimes:jpg,jpeg,png,gif|max:5120', + 'harga' => 'required|string', // wajib string karena ada titik + ]); - $template->fiturs()->sync($data['fitur_id']); + // hitung total harga dari fitur yang dipilih + $totalHarga = Fitur::whereIn('id', $data['fitur_id'])->sum('harga'); - return redirect()->route('templates.index')->with('success', 'Template berhasil ditambahkan!'); -} - - -public function update(Request $request, Template $template) -{ - $data = $request->validate([ - 'nama_template' => 'required|string|max:255', - 'kategori_id' => 'required|exists:kategoris,id', - 'fitur_id' => 'required|array', - 'fitur_id.*' => 'exists:fiturs,id', - 'foto' => 'nullable|image|mimes:jpg,jpeg,png,gif|max:5120', - ]); - - // hitung ulang harga - $totalHarga = Fitur::whereIn('id', $data['fitur_id'])->sum('harga'); - - if ($request->hasFile('foto')) { - if ($template->foto && Storage::disk('public')->exists($template->foto)) { - Storage::disk('public')->delete($template->foto); + if ($request->hasFile('foto')) { + $data['foto'] = $request->file('foto')->store('templates', 'public'); } - $data['foto'] = $request->file('foto')->store('templates', 'public'); + + // Bersihkan titik ribuan sebelum simpan + $hargaBersih = (int) str_replace('.', '', $request->harga); + + // store + $template = Template::create([ + 'nama_template' => $data['nama_template'], + 'kategori_id' => $data['kategori_id'], + 'foto' => $data['foto'] ?? null, + 'harga' => $hargaBersih, + ]); + + $template->fiturs()->sync($data['fitur_id']); + + return redirect()->route('templates.index')->with('success', 'Template berhasil ditambahkan!'); } -// update -$template->update([ - 'nama_template' => $data['nama_template'], - 'kategori_id' => $data['kategori_id'], - 'foto' => $data['foto'] ?? $template->foto, - 'harga' => $request->harga, // ✅ ambil langsung dari input -]); + public function update(Request $request, Template $template) + { + $data = $request->validate([ + 'nama_template' => 'required|string|max:255', + 'kategori_id' => 'required|exists:kategoris,id', + 'fitur_id' => 'required|array', + 'fitur_id.*' => 'exists:fiturs,id', + 'foto' => 'nullable|image|mimes:jpg,jpeg,png,gif|max:5120', + 'harga' => 'required|string', + ]); - $template->fiturs()->sync($data['fitur_id']); + // hitung ulang harga fitur + $totalHarga = Fitur::whereIn('id', $data['fitur_id'])->sum('harga'); - return redirect()->route('templates.index')->with('success', 'Template berhasil diperbarui!'); -} + if ($request->hasFile('foto')) { + if ($template->foto && Storage::disk('public')->exists($template->foto)) { + Storage::disk('public')->delete($template->foto); + } + $data['foto'] = $request->file('foto')->store('templates', 'public'); + } + + // Bersihkan titik ribuan + $hargaBersih = (int) str_replace('.', '', $request->harga); + + // update + $template->update([ + 'nama_template' => $data['nama_template'], + 'kategori_id' => $data['kategori_id'], + 'foto' => $data['foto'] ?? $template->foto, + 'harga' => $hargaBersih, + ]); + + $template->fiturs()->sync($data['fitur_id']); + + return redirect()->route('templates.index')->with('success', 'Template berhasil diperbarui!'); + } public function destroy(Template $template) { @@ -97,23 +102,21 @@ $template->update([ Storage::disk('public')->delete($template->foto); } - // detach fiturs otomatis karena cascade on pivot, tapi bisa explicit: $template->fiturs()->detach(); - $template->delete(); + return redirect()->route('templates.index')->with('success', 'Template berhasil dihapus!'); } -public function byKategori($id) -{ - $kategori = Kategori::findOrFail($id); - $templates = Template::with(['kategori', 'fiturs']) - ->where('kategori_id', $id) - ->paginate(5); // ✅ pakai paginate - $kategoris = Kategori::all(); - $fiturs = Fitur::all(); - - return view('admin.templates.index', compact('templates', 'kategoris', 'fiturs', 'kategori')); -} + public function byKategori($id) + { + $kategori = Kategori::findOrFail($id); + $templates = Template::with(['kategori', 'fiturs']) + ->where('kategori_id', $id) + ->paginate(5); + $kategoris = Kategori::all(); + $fiturs = Fitur::all(); + return view('admin.templates.index', compact('templates', 'kategoris', 'fiturs', 'kategori')); + } } diff --git a/backend/resources/views/admin/templates/index.blade.php b/backend/resources/views/admin/templates/index.blade.php index f8a16c1..91988b9 100644 --- a/backend/resources/views/admin/templates/index.blade.php +++ b/backend/resources/views/admin/templates/index.blade.php @@ -251,7 +251,7 @@
-
@@ -448,20 +448,33 @@ document.addEventListener('DOMContentLoaded', () => { } // ========================= - // Fitur: Hitung Harga Otomatis - // ========================= - function hitungHarga(container) { - let total = 0; - container.querySelectorAll('input[name="fitur_id[]"]:checked').forEach(cb => { - total += parseInt(cb.dataset.harga) || 0; - }); +// Fitur: Hitung Harga Otomatis + Format ribuan +// ========================= +function formatRibuan(x) { + if (!x) return ''; + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."); +} - const inputHarga = container.querySelector('input[name="harga"]'); - // hanya update kalau user belum ubah manual - if (inputHarga && !inputHarga.dataset.manual) { - inputHarga.value = total; - } +function hitungHarga(container) { + let total = 0; + container.querySelectorAll('input[name="fitur_id[]"]:checked').forEach(cb => { + total += parseInt(cb.dataset.harga) || 0; + }); + + const inputHarga = container.querySelector('input[name="harga"]'); + if (inputHarga && !inputHarga.dataset.manual) { + inputHarga.value = formatRibuan(total); } +} + +// Update input text agar bisa ketik manual dengan format ribuan +document.querySelectorAll('.harga-input').forEach(input => { + input.addEventListener('input', (e) => { + let value = e.target.value.replace(/\D/g, ''); // hanya angka + e.target.value = formatRibuan(value); + e.target.dataset.manual = "true"; // kasih flag manual + }); +}); // Modal Tambah if (modalTambah) {