From ea5ad05de93aa4f1e6a308ce2ac84031e9af6877 Mon Sep 17 00:00:00 2001 From: ariefabbauftech-ai Date: Wed, 17 Sep 2025 12:44:52 +0700 Subject: [PATCH] [Fitur BE] --- .../app/Http/Controllers/FiturController.php | 63 +-- .../Http/Controllers/TemplateController.php | 105 ++-- backend/app/Models/Fitur.php | 8 +- ...25_09_03_042108_create_templates_table.php | 18 +- ...09_17_040752_add_harga_to_fiturs_table.php | 22 + .../resources/views/admin/dashboard.blade.php | 319 +++++------ .../views/admin/fitur/index.blade.php | 502 +++++++++--------- 7 files changed, 501 insertions(+), 536 deletions(-) create mode 100644 backend/database/migrations/2025_09_17_040752_add_harga_to_fiturs_table.php diff --git a/backend/app/Http/Controllers/FiturController.php b/backend/app/Http/Controllers/FiturController.php index 202b103..e69164b 100644 --- a/backend/app/Http/Controllers/FiturController.php +++ b/backend/app/Http/Controllers/FiturController.php @@ -1,56 +1,59 @@ validate([ + 'deskripsi' => 'required|string|max:255', + 'harga' => 'required|numeric|min:0', + ]); + + Fitur::create([ + 'deskripsi' => $request->deskripsi, + 'harga' => $request->harga, + ]); + + return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil ditambahkan'); } - // Simpan fitur baru -public function store(Request $request) -{ - $data = $request->validate([ - 'deskripsi' => 'required|string', - ]); - - Fitur::create($data); - - return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil ditambahkan!'); -} - -public function update(Request $request, Fitur $fitur) -{ - $data = $request->validate([ - 'deskripsi' => 'required|string', - ]); - - $fitur->update($data); - - return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil diperbarui!'); -} + // Update fitur + public function update(Request $request, $id) + { + $request->validate([ + 'deskripsi' => 'required|string|max:255', + 'harga' => 'required|numeric|min:0', + ]); + $fitur = Fitur::findOrFail($id); + $fitur->update([ + 'deskripsi' => $request->deskripsi, + 'harga' => $request->harga, + ]); + return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil diperbarui'); + } // Hapus fitur - public function destroy(Fitur $fitur) + public function destroy($id) { + $fitur = Fitur::findOrFail($id); $fitur->delete(); - return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil dihapus!'); + return redirect()->route('admin.fitur.index')->with('success', 'Fitur berhasil dihapus'); } } diff --git a/backend/app/Http/Controllers/TemplateController.php b/backend/app/Http/Controllers/TemplateController.php index 39d8069..410ffd9 100644 --- a/backend/app/Http/Controllers/TemplateController.php +++ b/backend/app/Http/Controllers/TemplateController.php @@ -27,66 +27,67 @@ public function show($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', - 'harga' => 'required|numeric|min:0' - ]); +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', + ]); - if ($request->hasFile('foto')) { - $data['foto'] = $request->file('foto')->store('templates', 'public'); - } + // hitung total harga dari fitur yang dipilih + $totalHarga = Fitur::whereIn('id', $data['fitur_id'])->sum('harga'); - // create template (tanpa fitur) - $template = Template::create([ - 'nama_template' => $data['nama_template'], - 'kategori_id' => $data['kategori_id'], - 'foto' => $data['foto'] ?? null, - 'harga' => $data['harga'], - ]); - - // sync fitur ke pivot - $template->fiturs()->sync($data['fitur_id'] ?? []); - - return redirect()->route('templates.index')->with('success', 'Template berhasil ditambahkan!'); + if ($request->hasFile('foto')) { + $data['foto'] = $request->file('foto')->store('templates', 'public'); } - 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|numeric|min:0' - ]); + $template = Template::create([ + 'nama_template' => $data['nama_template'], + 'kategori_id' => $data['kategori_id'], + 'foto' => $data['foto'] ?? null, + 'harga' => $totalHarga, // ✅ otomatis dari fitur + ]); - 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'); + $template->fiturs()->sync($data['fitur_id']); + + 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); } - - $template->update([ - 'nama_template' => $data['nama_template'], - 'kategori_id' => $data['kategori_id'], - 'foto' => $data['foto'] ?? $template->foto, - 'harga' => $data['harga'], - ]); - - // update pivot - $template->fiturs()->sync($data['fitur_id'] ?? []); - - return redirect()->route('templates.index')->with('success', 'Template berhasil diperbarui!'); + $data['foto'] = $request->file('foto')->store('templates', 'public'); } + $template->update([ + 'nama_template' => $data['nama_template'], + 'kategori_id' => $data['kategori_id'], + 'foto' => $data['foto'] ?? $template->foto, + 'harga' => $totalHarga, // ✅ otomatis dari fitur + ]); + + $template->fiturs()->sync($data['fitur_id']); + + return redirect()->route('templates.index')->with('success', 'Template berhasil diperbarui!'); +} + public function destroy(Template $template) { if ($template->foto && Storage::disk('public')->exists($template->foto)) { diff --git a/backend/app/Models/Fitur.php b/backend/app/Models/Fitur.php index 22b6ca1..083086b 100644 --- a/backend/app/Models/Fitur.php +++ b/backend/app/Models/Fitur.php @@ -3,14 +3,12 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; - -class Fitur extends Model + class Fitur extends Model { - protected $fillable = ['deskripsi']; + protected $fillable = ['deskripsi', 'harga']; - // many-to-many public function templates() { return $this->belongsToMany(Template::class, 'fitur_template'); } -} +} \ No newline at end of file diff --git a/backend/database/migrations/2025_09_03_042108_create_templates_table.php b/backend/database/migrations/2025_09_03_042108_create_templates_table.php index f98c705..5b9b3c2 100644 --- a/backend/database/migrations/2025_09_03_042108_create_templates_table.php +++ b/backend/database/migrations/2025_09_03_042108_create_templates_table.php @@ -7,15 +7,15 @@ use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { - Schema::create('templates', function (Blueprint $table) { - $table->id(); - $table->string('nama_template'); - $table->foreignId('kategori_id')->constrained()->cascadeOnDelete(); - $table->foreignId('fitur_id')->constrained()->cascadeOnDelete(); - $table->decimal('harga', 10, 2)->default(0); - $table->string('foto')->nullable(); - $table->timestamps(); - }); + // database/migrations/2025_09_08_000003_create_templates_table.php +Schema::create('templates', function (Blueprint $table) { + $table->id(); + $table->string('nama_template'); + $table->foreignId('kategori_id')->constrained()->cascadeOnDelete(); + $table->decimal('harga', 10, 2)->default(0); // ✅ harga template + $table->string('foto')->nullable(); + $table->timestamps(); +}); } public function down(): void { diff --git a/backend/database/migrations/2025_09_17_040752_add_harga_to_fiturs_table.php b/backend/database/migrations/2025_09_17_040752_add_harga_to_fiturs_table.php new file mode 100644 index 0000000..f147f26 --- /dev/null +++ b/backend/database/migrations/2025_09_17_040752_add_harga_to_fiturs_table.php @@ -0,0 +1,22 @@ + decimal('harga', 10, 2)->default(0)->after('deskripsi'); + }); + } + + public function down(): void + { + Schema::table('fiturs', function (Blueprint $table) { + $table->dropColumn('harga'); + }); + } + }; diff --git a/backend/resources/views/admin/dashboard.blade.php b/backend/resources/views/admin/dashboard.blade.php index d048d77..cdff7ce 100644 --- a/backend/resources/views/admin/dashboard.blade.php +++ b/backend/resources/views/admin/dashboard.blade.php @@ -1,232 +1,157 @@ @extends('layouts.app') -@section('title', 'Halaman Dasbor') +@section('title', 'Manajemen Template') @section('content') -
- -
-

Halaman Dasbor

-
-
- - {{ $today }} -
-
+
+
+

Manajemen Template

+
- -
-
-
-
Kategori
-

{{ $totalKategori }}

-
-
- -
-
-
-
-
Template
-

{{ $totalTemplate }}

-
-
- -
-
-
-
-
Pelanggan
-

{{ $totalPelanggan }}

-
-
- -
-
-
- - -
-
-

Pelanggan Terbaru

- - + +
+
+
+ - - - - - - - - - + + + + + + - @forelse($recentPelanggan as $index => $pelanggan) + @forelse($templates as $index => $template) - + + + + - - - - - - - - @empty - + @endforelse
NomorNamaTemplateKategoriEmailNo. TeleponHargaTanggal PemesananAksiNomorNama TemplateKategoriHargaFiturAksi
- {{ $recentPelanggan->firstItem() + $index }} + {{ $templates->firstItem() + $index }}{{ $template->nama_template }}{{ $template->kategori->nama_kategori ?? '-' }}Rp {{ number_format($template->harga, 0, ',', '.') }} + @foreach ($template->fiturs as $fitur) + {{ $fitur->nama_fitur }} + @endforeach {{ $pelanggan->nama_pemesan }}{{ $pelanggan->nama_template }}{{ $pelanggan->kategori ?? '-' }}{{ $pelanggan->email }}{{ $pelanggan->no_tlpn ?? '-' }} - Rp {{ number_format($pelanggan->harga, 0, ',', '.') }} - - {{ \Carbon\Carbon::parse($pelanggan->created_at)->format('d M Y') }} - -
- - Detail - -
+ + + + + + +
+ @csrf + @method('DELETE') + - +
- Belum ada data pelanggan. - Belum ada template
- -
-
- {{-- Tombol Previous --}} - @if ($recentPelanggan->onFirstPage()) - Prev - @else - Prev - @endif - - @php - $total = $recentPelanggan->lastPage(); - $current = $recentPelanggan->currentPage(); - @endphp - - {{-- Selalu tampilkan halaman pertama --}} - @if ($current > 2) - 1 - @if ($current > 3) - ... - @endif - @endif - - {{-- Hanya tampilkan 3 halaman di tengah (current-1, current, current+1) --}} - @for ($i = max(1, $current - 1); $i <= min($total, $current + 1); $i++) - @if ($i == $current) - {{ $i }} - @else - {{ $i }} - @endif - @endfor - - {{-- Selalu tampilkan halaman terakhir --}} - @if ($current < $total - 1) - @if ($current < $total - 2) - ... - @endif - {{ $total }} - @endif - - {{-- Tombol Next --}} - @if ($recentPelanggan->hasMorePages()) - Next - @else - Next - @endif -
+
+ {{ $templates->links() }}
+
- - @foreach ($recentPelanggan as $pelanggan) -