From 6097b439fc5d5a37f39d074f49768da8db47d134 Mon Sep 17 00:00:00 2001 From: sayasilvi Date: Mon, 2 Mar 2026 03:20:52 +0700 Subject: [PATCH] feat: tambahkan grafik produk terlaris & kestabilan harga di dashboard admin, hapus fitur verifikasi petani --- .../Controllers/Admin/AdminController.php | 76 +++--- app/Http/Controllers/TransaksiController.php | 9 +- resources/views/admin/dashboard.blade.php | 236 +++++++++++++----- 3 files changed, 209 insertions(+), 112 deletions(-) diff --git a/app/Http/Controllers/Admin/AdminController.php b/app/Http/Controllers/Admin/AdminController.php index 796dee0..8d7ea49 100644 --- a/app/Http/Controllers/Admin/AdminController.php +++ b/app/Http/Controllers/Admin/AdminController.php @@ -7,75 +7,63 @@ use App\Models\Petani; use App\Models\Produk; use App\Models\Transaksi; +use App\Models\DetailTransaksi; +use Illuminate\Support\Facades\DB; class AdminController extends Controller { public function dashboard() { + // STATISTIK $totalPetani = Petani::where('status_akun', 'aktif')->count(); - $petaniPending = Petani::where('status_akun', 'menunggu')->count(); $totalProduk = Produk::count(); $totalTransaksi = Transaksi::count(); + $transaksiTerbaru = Transaksi::with(['pembeli', 'petani'])->latest()->take(5)->get(); - $transaksiTerbaru = Transaksi::with(['pembeli', 'petani']) - ->latest() + // PRODUK TERLARIS + $produkTerlaris = Produk::withSum(['detailTransaksis as total_terjual' => function ($query) { + $query->whereHas('transaksi', function ($q) { + $q->where('status', '!=', 'batal'); + }); + }], 'jumlah') + ->orderByDesc('total_terjual') ->take(5) ->get(); + $labelTerlaris = $produkTerlaris->pluck('nama_produk'); + $dataTerlaris = $produkTerlaris->pluck('total_terjual'); + + // Menghitung rata-rata harga jual harian selama 7 hari terakhir + $hargaStabil = DetailTransaksi::join('transaksis', 'detail_transaksis.transaksi_id', '=', 'transaksis.id') + ->selectRaw('DATE(transaksis.tanggal_transaksi) as tanggal, AVG(detail_transaksis.harga_satuan) as rata_harga') + ->where('transaksis.status', '!=', 'batal') + ->groupBy('tanggal') + ->orderBy('tanggal', 'asc') + ->take(7) + ->get(); + + $labelHarga = $hargaStabil->pluck('tanggal')->map(function($date) { + return \Carbon\Carbon::parse($date)->format('d M'); + }); + $dataHarga = $hargaStabil->pluck('rata_harga'); + return view('admin.dashboard', compact( - 'totalPetani', - 'petaniPending', - 'totalProduk', - 'totalTransaksi', - 'transaksiTerbaru' + 'totalPetani', 'totalProduk', 'totalTransaksi', 'transaksiTerbaru', + 'labelTerlaris', 'dataTerlaris', 'labelHarga', 'dataHarga' )); } public function monitoring() { $produks = Produk::with('petani')->latest()->paginate(10); - $transaksis = Transaksi::with(['pembeli', 'petani']) - ->latest() - ->paginate(10); - + $transaksis = Transaksi::with(['pembeli', 'petani'])->latest()->paginate(10); return view('admin.monitoring', compact('produks', 'transaksis')); } public function transaksiDetail($id) { - $transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk']) - ->findOrFail($id); - + $transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk'])->findOrFail($id); return view('admin.transaksi_detail', compact('transaksi')); } - public function verifikasiIndex() - { - $petanis = Petani::orderBy('created_at', 'desc')->get(); - return view('admin.verifikasi.index', compact('petanis')); - } - - public function verifikasiShow($id) - { - $petani = Petani::findOrFail($id); - return view('admin.verifikasi.show', compact('petani')); - } - - public function verifikasiApprove($id) - { - $petani = Petani::findOrFail($id); - $petani->status_akun = 'aktif'; - $petani->save(); - - return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani BERHASIL diterima.'); - } - - public function verifikasiReject($id) - { - $petani = Petani::findOrFail($id); - $petani->status_akun = 'ditolak'; - $petani->save(); - - return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani DITOLAK.'); - } } \ No newline at end of file diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index e8de055..2440535 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -23,7 +23,7 @@ public function checkoutPage(Request $request) // Mendefinisikan ID Pembeli agar tidak error 'Undefined Variable' $pembeli_id = Auth::guard('pembeli')->id(); - // 1. LOGIKA BELI LANGSUNG (Buy Now) + // LOGIKA BELI LANGSUNG (Buy Now) if ($request->has('produk_id')) { $produk = Produk::with('petani')->findOrFail($request->produk_id); $items = collect([ @@ -41,7 +41,7 @@ public function checkoutPage(Request $request) return view('landing.checkout', compact('items', 'total_belanja')); } - // 2. LOGIKA CHECKOUT DARI KERANJANG (Database) + // LOGIKA CHECKOUT DARI KERANJANG (Database) $cartIds = $request->query('cart_ids'); if (!$cartIds) { @@ -50,7 +50,6 @@ public function checkoutPage(Request $request) $selectedIds = explode(',', $cartIds); - // Ambil data dari Tabel Cart yang ID-nya dicentang oleh user $cartItems = Cart::with('produk.petani') ->where('pembeli_id', $pembeli_id) ->whereIn('id', $selectedIds) @@ -132,7 +131,6 @@ public function prosesCheckout(Request $request) ->where('pembeli_id', $pembeli_id) ->get(); - // Kelompokkan produk berdasarkan Petani ID agar Invoice terpisah per toko $groupedByPetani = []; foreach ($cartItems as $item) { $groupedByPetani[$item->produk->petani_id][] = $item; @@ -144,7 +142,7 @@ public function prosesCheckout(Request $request) 'petani_id' => $petani_id, 'tanggal_transaksi' => now(), 'alamat_pengiriman' => $request->alamat_pengiriman, - 'total_harga' => 0, // Diupdate setelah menghitung subtotal + 'total_harga' => 0, 'status' => 'menunggu konfirmasi', 'kode_invoice' => 'INV/' . date('Ymd') . '/' . rand(1000, 9999), ]); @@ -169,7 +167,6 @@ public function prosesCheckout(Request $request) $transaksi->update(['total_harga' => $subtotal_transaksi]); } - // OTOMATIS BERSIHKAN ITEM KERANJANG YANG SUDAH DIBELI Cart::whereIn('id', $cartIds)->delete(); } }); diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 7afdf45..ffa569a 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -6,45 +6,27 @@ @section('content')
+ + {{-- STATISTIK ATAS --}}
- {{-- Statistik Petani Aktif --}} -
-
-
+
+
+
-
Petani Aktif
+
Total Petani
{{ $totalPetani }}
- - {{-- Statistik Menunggu Verifikasi --}} -
-
-
-
-
-
-
-
-
Verifikasi Masuk
-
{{ $petaniPending }}
-
-
-
-
-
- - {{-- Statistik Total Produk --}} -
-
-
+
+
+
@@ -57,11 +39,9 @@
- - {{-- Statistik Total Transaksi --}} -
-
-
+
+
+
@@ -76,14 +56,41 @@
- {{-- Tabel Ringkasan Transaksi --}} + {{-- AREA GRAFIK BERSEBELAHAN --}} +
+ {{-- Kiri: Grafik Produk Terlaris --}} +
+
+
+
Produk Terlaris
+
+
+ +
+
+
+ + {{-- Kanan: Grafik Kestabilan Harga --}} +
+
+
+
Kestabilan Harga Jual Petani
+
+
+ +
+
+
+
+ + {{-- TABEL TRANSAKSI TERBARU (SAMA SEPERTI SEBELUMNYA) --}}
-
-
-

Transaksi Terbaru di Platform

+
+
+
Transaksi Terbaru di Platform
-
+
@@ -102,20 +109,12 @@ - - - - @empty - - - + @endforelse
#{{ $trx->kode_invoice }}
- - {{ $trx->petani->nama_lengkap ?? 'Petani Tidak Ditemukan' }} - - - - {{ $trx->petani->nama_usaha ?? '-' }} - + {{ $trx->petani->nama_lengkap ?? 'Petani Tidak Ditemukan' }} + {{ $trx->petani->nama_usaha ?? '-' }}
{{ $trx->pembeli->nama_lengkap ?? 'Guest' }}Rp {{ number_format($trx->total_harga, 0, ',', '.') }} @php $badgeClass = match ($trx->status) { @@ -127,30 +126,18 @@ default => 'bg-secondary', }; @endphp - - {{ ucwords($trx->status) }} - + {{ ucwords($trx->status) }} {{ $trx->created_at->format('d M Y') }}
-
- - Belum ada transaksi baru. -
-
Belum ada transaksi baru.
@@ -158,4 +145,129 @@
+@endsection + +@section('js') +{{-- Load library Chart.js --}} + + + @endsection \ No newline at end of file