refactor: ui pembeli, petani and admin include card adjustmen with optimalization query

This commit is contained in:
sayasilvi 2025-12-25 16:24:28 +07:00
parent 95f769db87
commit b20dd54a6c
27 changed files with 970 additions and 744 deletions

View File

@ -1,7 +1,8 @@
<?php <?php
namespace App\Http\Controllers; namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Petani; use App\Models\Petani;
use App\Models\Produk; use App\Models\Produk;
@ -40,7 +41,6 @@ public function monitoring()
return view('admin.monitoring', compact('produks', 'transaksis')); return view('admin.monitoring', compact('produks', 'transaksis'));
} }
// --- FITUR BARU: DETAIL TRANSAKSI ---
public function transaksiDetail($id) public function transaksiDetail($id)
{ {
$transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk']) $transaksi = Transaksi::with(['pembeli', 'petani', 'detailTransaksis.produk'])
@ -49,39 +49,30 @@ public function transaksiDetail($id)
return view('admin.transaksi_detail', compact('transaksi')); return view('admin.transaksi_detail', compact('transaksi'));
} }
// --- VERIFIKASI PETANI ---
public function verifikasiIndex() public function verifikasiIndex()
{ {
// Ambil data petani yang statusnya 'menunggu'
$petanis = Petani::orderBy('created_at', 'desc')->get(); $petanis = Petani::orderBy('created_at', 'desc')->get();
return view('admin.verifikasi.index', compact('petanis')); return view('admin.verifikasi.index', compact('petanis'));
} }
// Tampilkan Detail Petani
public function verifikasiShow($id) public function verifikasiShow($id)
{ {
$petani = Petani::findOrFail($id); $petani = Petani::findOrFail($id);
return view('admin.verifikasi.show', compact('petani')); return view('admin.verifikasi.show', compact('petani'));
} }
// Proses Terima Pendaftaran (Approve)
public function verifikasiApprove($id) public function verifikasiApprove($id)
{ {
$petani = Petani::findOrFail($id); $petani = Petani::findOrFail($id);
$petani->status_akun = 'aktif'; $petani->status_akun = 'aktif';
$petani->save(); $petani->save();
return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani BERHASIL diterima.'); return redirect('admin/verifikasi')->with('success', 'Pendaftaran Petani BERHASIL diterima.');
} }
// Proses Tolak Pendaftaran (Reject)
public function verifikasiReject($id) public function verifikasiReject($id)
{ {
$petani = Petani::findOrFail($id); $petani = Petani::findOrFail($id);
$petani->status_akun = 'ditolak'; $petani->status_akun = 'ditolak';
$petani->save(); $petani->save();

View File

@ -4,61 +4,95 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Produk; use App\Models\Produk;
use App\Models\Cart;
use Illuminate\Support\Facades\Auth;
class CartController extends Controller class CartController extends Controller
{ {
// Menampilkan Halaman Keranjang // Menampilkan Halaman Keranjang
public function index() public function index()
{ {
$cart = session()->get('cart', []); // Cek Login Pembeli
if (!Auth::guard('pembeli')->check()) {
return redirect()->route('login')->with('error', 'Silakan login terlebih dahulu untuk melihat keranjang.');
}
$pembeli_id = Auth::guard('pembeli')->id();
// Ambil data keranjang dari Database
$cart = Cart::with('produk')->where('pembeli_id', $pembeli_id)->get();
return view('landing.cart', compact('cart')); return view('landing.cart', compact('cart'));
} }
// Menambahkan Produk ke Session Keranjang // Menambahkan Produk ke DB Keranjang
public function addToCart(Request $request) public function addToCart(Request $request)
{ {
$id = $request->id; // Validasi Login
$produk = Produk::findOrFail($id); if (!Auth::guard('pembeli')->check()) {
return redirect()->route('login')->with('error', 'Silakan login dulu untuk belanja!');
$cart = session()->get('cart', []); }
// Validasi qty default ke 1 jika kosong $produk_id = $request->id;
$quantity = $request->qty ? $request->qty : 1; $pembeli_id = Auth::guard('pembeli')->id();
$quantity = $request->qty ? $request->qty : 1;
if (isset($cart[$id])) {
$cart[$id]['quantity'] += $quantity; // Cek stok produk
} else { $produk = Produk::find($produk_id);
$cart[$id] = [ if ($produk->stok < $quantity) {
"name" => $produk->nama_produk, return redirect()->back()->with('error', 'Stok produk tidak mencukupi.');
"quantity" => $quantity, }
"price" => $produk->harga,
"photo" => $produk->foto_produk // Cek produk yang ada di keranjang database user
]; $existingCart = Cart::where('pembeli_id', $pembeli_id)
->where('produk_id', $produk_id)
->first();
if ($existingCart) {
$existingCart->quantity += $quantity;
$existingCart->save();
} else {
Cart::create([
'pembeli_id' => $pembeli_id,
'produk_id' => $produk_id,
'quantity' => $quantity
]);
} }
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Produk berhasil masuk keranjang!'); return redirect()->back()->with('success', 'Produk berhasil masuk keranjang!');
} }
public function updateCart(Request $request) public function updateCart(Request $request)
{ {
if (!Auth::guard('pembeli')->check()) {
return response()->json(['status' => 'error', 'message' => 'Unauthorized']);
}
if ($request->id && $request->quantity) { if ($request->id && $request->quantity) {
$cart = session()->get('cart'); $cartItem = Cart::where('id', $request->id)
$cart[$request->id]["quantity"] = $request->quantity; ->where('pembeli_id', Auth::guard('pembeli')->id())
session()->put('cart', $cart); ->first();
session()->flash('success', 'Keranjang berhasil diperbarui');
if ($cartItem) {
$cartItem->quantity = $request->quantity;
$cartItem->save();
session()->flash('success', 'Keranjang berhasil diperbarui');
}
} }
} }
// Menghapus Item dari Keranjang // Menghapus Item dari DB Keranjang
public function remove(Request $request) public function remove(Request $request)
{ {
if (!Auth::guard('pembeli')->check()) {
return redirect()->route('login');
}
if ($request->id) { if ($request->id) {
$cart = session()->get('cart'); Cart::where('id', $request->id)
if (isset($cart[$request->id])) { ->where('pembeli_id', Auth::guard('pembeli')->id())
unset($cart[$request->id]); ->delete();
session()->put('cart', $cart);
}
return redirect()->back()->with('success', 'Produk dihapus dari keranjang'); return redirect()->back()->with('success', 'Produk dihapus dari keranjang');
} }
} }

View File

@ -10,11 +10,17 @@ class LandingController extends Controller
public function index(Request $request) public function index(Request $request)
{ {
$query = Produk::with('petani')->latest(); $query = Produk::with('petani')->latest();
if ($request->has('kategori') && $request->kategori != '' && $request->kategori != 'Semua') { if ($request->has('kategori') && $request->kategori != '' && $request->kategori != 'Semua') {
$query->where('kategori', $request->kategori); $slug = $request->kategori;
$query->whereHas('kategori', function ($q) use ($slug) {
$q->where('slug', $slug);
});
} }
$produks = $query->take(8)->get(); $produks = $query->take(8)->get();
if ($request->ajax()) { if ($request->ajax()) {
return view('landing.partials.product_list', compact('produks'))->render(); return view('landing.partials.product_list', compact('produks'))->render();
} }
@ -35,16 +41,19 @@ public function shop(Request $request)
{ {
$query = Produk::where('stok', '>', 0); $query = Produk::where('stok', '>', 0);
// Filter Kategori Berdasarkan Slug if ($request->has('search') && $request->search != '') {
$query->where('nama_produk', 'like', '%' . $request->search . '%');
}
// Filter Kategori
if ($request->has('kategori') && $request->kategori != '') { if ($request->has('kategori') && $request->kategori != '') {
$slug = $request->kategori; $slug = $request->kategori;
$query->whereHas('kategori', function ($q) use ($slug) { $query->whereHas('kategori', function ($q) use ($slug) {
$q->where('slug', $slug); $q->where('slug', $slug);
}); });
} }
// Sorting (Urutkan) // Sorting
if ($request->has('sort')) { if ($request->has('sort')) {
switch ($request->sort) { switch ($request->sort) {
case 'termurah': case 'termurah':

View File

@ -13,23 +13,31 @@ public function index()
{ {
$petaniId = Auth::guard('petani')->id(); $petaniId = Auth::guard('petani')->id();
// // 1. Hitung Total Produk Aktif
$totalProduk = Produk::where('petani_id', $petaniId)->count(); $totalProduk = Produk::where('petani_id', $petaniId)->count();
// Hitung Pesanan Baru // 2. Hitung Pesanan Baru (Yang statusnya 'dibayar' / perlu diproses)
$pesananBaru = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) { $pesananBaru = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) {
$q->where('petani_id', $petaniId); $q->where('petani_id', $petaniId);
})->whereHas('transaksi', function($q) { })->whereHas('transaksi', function($q) {
$q->where('status', 'dibayar'); $q->where('status', 'dibayar');
})->count(); })->count();
// Hitung Total Pendapatan // 3. Hitung TOTAL SEMUA PEMESANAN (Valid)
// Menghitung semua transaksi masuk (Dibayar, Dikirim, Selesai) kecuali yang Batal
$totalPemesanan = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) {
$q->where('petani_id', $petaniId);
})->whereHas('transaksi', function($q) {
$q->where('status', '!=', 'batal'); // Ambil semua kecuali yang batal
})->count();
// 4. Hitung Total Pendapatan (Hanya yang status 'selesai')
$totalPendapatan = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) { $totalPendapatan = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) {
$q->where('petani_id', $petaniId); $q->where('petani_id', $petaniId);
})->whereHas('transaksi', function($q) { })->whereHas('transaksi', function($q) {
$q->where('status', 'selesai'); $q->where('status', 'selesai');
})->sum('subtotal'); })->sum('subtotal');
return view('petani.dashboard', compact('totalProduk', 'pesananBaru', 'totalPendapatan')); return view('petani.dashboard', compact('totalProduk', 'pesananBaru', 'totalPemesanan', 'totalPendapatan'));
} }
} }

25
app/Models/Cart.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Cart extends Model
{
use HasFactory;
protected $fillable = ['pembeli_id', 'produk_id', 'quantity'];
// Relasi ke Produk
public function produk()
{
return $this->belongsTo(Produk::class, 'produk_id');
}
// Relasi ke Pembeli
public function pembeli()
{
return $this->belongsTo(Pembeli::class, 'pembeli_id');
}
}

View File

@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('carts', function (Blueprint $table) {
$table->id();
$table->foreignId('pembeli_id')->constrained('pembelis')->onDelete('cascade');
$table->foreignId('produk_id')->constrained('produks')->onDelete('cascade');
$table->integer('quantity')->default(1);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('carts');
}
};

View File

@ -159,7 +159,7 @@ @media (min-width: 1200px) {
.dropdown .dropdown-menu a:hover { .dropdown .dropdown-menu a:hover {
background: var(--bs-secondary); background: var(--bs-secondary);
color: var(--bs-primary); color: var(--bs-primary);z
} }
.navbar .nav-item:hover .dropdown-menu { .navbar .nav-item:hover .dropdown-menu {

View File

@ -33,7 +33,7 @@
<div class="stats-icon red"><i class="bi bi-person-plus-fill"></i></div> <div class="stats-icon red"><i class="bi bi-person-plus-fill"></i></div>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<h6 class="text-muted font-semibold">Verifikasi Pending</h6> <h6 class="text-muted font-semibold">Verifikasi Masuk</h6>
<h6 class="font-extrabold mb-0">{{ $petaniPending }}</h6> <h6 class="font-extrabold mb-0">{{ $petaniPending }}</h6>
</div> </div>
</div> </div>

View File

@ -2,18 +2,23 @@
@section('title', 'Detail Transaksi') @section('title', 'Detail Transaksi')
@section('page-title')
<div class="d-flex align-items-center justify-content-between">
<div>
<div class="d-flex align-items-center gap-1 mb-1">
<a href="{{ route('admin.monitoring') }}">Daftar Transaksi </a>
<p class="mb-0">/ Detail Pesanan</p>
</div>
<p class="text-muted font-bold mb-0">Invoice: #{{ $transaksi->kode_invoice }}</p>
</div>
<a href="{{ route('petani.pesanan.index') }}" class="btn btn-light">
<i class="bi bi-arrow-left"></i> Kembali
</a>
</div>
@endsection
@section('content') @section('content')
<div class="container-fluid"> <div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h3 class="mb-0">Detail Transaksi</h3>
<span class="text-muted">Invoice: #{{ $transaksi->kode_invoice }}</span>
</div>
<a href="{{ route('admin.monitoring') }}" class="btn btn-secondary">
<i class="bi bi-arrow-left"></i> Kembali
</a>
</div>
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<div class="card mb-4 border-0 shadow-sm" style="border-radius: 12px; overflow: hidden;"> <div class="card mb-4 border-0 shadow-sm" style="border-radius: 12px; overflow: hidden;">

View File

@ -1,75 +1,201 @@
@extends('layouts.admin') @extends('layouts.admin')
@section('title', 'Detail Petani') @section('title', 'Detail Petani')
@section('page-title', 'Detail Calon Petani') @section('page-title')
<div>
@section('content') <div class="d-flex align-items-center gap-1 mb-1">
<div class="row"> <a href="{{ route('admin.verifikasi.index') }}">Daftar Verifikasi </a>
<div class="col-md-6"> <p class="mb-0">/ Detail Verifikasi Akun Petani</p>
<div class="card">
<div class="card-header">
<h4>Data Diri</h4>
</div> </div>
<div class="card-body"> </div>
<table class="table table-borderless"> @endsection
@section('content')
<div class="mb-4">
<a href="{{ url('admin/verifikasi') }}" class="text-decoration-none text-muted">
<i class="bi bi-arrow-left me-1"></i> Kembali ke Daftar Antrian
</a>
</div>
<div class="row g-4">
{{-- 1. KOLOM KIRI: DATA LENGKAP (Desain Clean List - Pilihan Kamu) --}}
<div class="col-12 col-lg-8">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white py-4 border-bottom-0">
<div class="d-flex justify-content-between align-items-center">
<h5 class="fw-bold m-0 text-dark">
<i class="bi bi-person-lines-fill me-2 text-primary"></i>Data Calon Petani
</h5>
{{-- Badge Status di Header Kiri --}}
@if($petani->status_akun == 'menunggu')
<span class="badge bg-warning text-dark"><i class="bi bi-hourglass-split me-1"></i> Menunggu Verifikasi</span>
@elseif($petani->status_akun == 'aktif')
<span class="badge bg-success"><i class="bi bi-check-circle me-1"></i> Terverifikasi</span>
@else
<span class="badge bg-danger"><i class="bi bi-x-circle me-1"></i> Ditolak</span>
@endif
</div>
</div>
<div class="card-body px-4 pb-4 pt-0">
<table class="table table-borderless align-middle mb-0">
<tr> <tr>
<th>Nama Lengkap</th> <td class="text-muted small text-uppercase fw-bold pt-3" width="30%">Nama Lengkap</td>
<td>: {{ $petani->nama_lengkap }}</td> <td class="pt-3 fw-bold text-dark fs-5">{{ $petani->nama_lengkap }}</td>
</tr> </tr>
<tr> <tr>
<th>Username</th> <td class="text-muted small text-uppercase fw-bold">Username</td>
<td>: {{ $petani->username }}</td> <td class="fw-medium">{{ $petani->username }}</td>
</tr> </tr>
<tr> <tr>
<th>No HP</th> <td class="text-muted small text-uppercase fw-bold">Nomor WhatsApp</td>
<td>: {{ $petani->no_hp }}</td> <td>
</tr> <span class="bg-light px-2 py-1 rounded fw-bold text-dark font-monospace">{{ $petani->no_hp }}</span>
<tr> <a href="https://wa.me/{{ $petani->no_hp }}" target="_blank" class="ms-2 text-decoration-none small text-success fw-bold">
<th>Alamat</th> <i class="bi bi-whatsapp"></i> Chat
<td>: {{ $petani->alamat }}</td> </a>
</tr>
<tr>
<th>Nama Usaha</th>
<td>: {{ $petani->nama_usaha }}</td>
</tr>
<tr>
<th>Status Saat Ini</th>
<td>:
<span class="badge bg-{{ $petani->status_akun == 'menunggu' ? 'warning' : ($petani->status_akun == 'aktif' ? 'success' : 'danger') }}">
{{ ucfirst($petani->status_akun) }}
</span>
</td> </td>
</tr> </tr>
<tr>
<td class="text-muted small text-uppercase fw-bold">Nama Usaha Tani</td>
<td class="fw-medium">{{ $petani->nama_usaha }}</td>
</tr>
<tr>
<td class="text-muted small text-uppercase fw-bold">Alamat Lengkap</td>
<td class="text-secondary" style="line-height: 1.6;">{{ $petani->alamat }}</td>
</tr>
<tr>
<td class="text-muted small text-uppercase fw-bold">Terdaftar Sejak</td>
<td class="text-secondary">{{ $petani->created_at->format('d F Y, H:i') }} WIB</td>
</tr>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-6"> {{-- 2. KOLOM KANAN: TIMELINE & AKSI (Log Style) --}}
<div class="card"> <div class="col-12 col-lg-4">
<div class="card-header"> <div class="card border-0 shadow-sm h-100">
<h4>Aksi Verifikasi</h4> <div class="card-header bg-white py-3">
<h6 class="fw-bold m-0 text-secondary"><i class="bi bi-clock-history me-2"></i>Riwayat Status</h6>
</div> </div>
<div class="card-body"> <div class="card-body p-4 d-flex flex-column">
<p>Silakan tinjau data di samping. Jika valid, klik Terima.</p>
<form action="{{ url('admin/verifikasi/'.$petani->id.'/approve') }}" method="POST" class="d-inline"> {{-- TIMELINE LOG --}}
@csrf <div class="timeline-wrapper mb-4">
<button type="submit" class="btn btn-success btn-lg w-100 mb-2" onclick="return confirm('Yakin ingin menerima petani ini?')">
<i class="bi bi-check-circle"></i> Terima Pendaftaran
</button>
</form>
<form action="{{ url('admin/verifikasi/'.$petani->id.'/reject') }}" method="POST" class="d-inline"> {{-- STEP 1: REGISTRASI (Pasti Ada) --}}
@csrf <div class="d-flex align-items-start mb-4">
<button type="submit" class="btn btn-danger btn-lg w-100" onclick="return confirm('Yakin ingin menolak petani ini?')"> <div class="d-flex flex-column align-items-center me-3">
<i class="bi bi-x-circle"></i> Tolak Pendaftaran <div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center shadow-sm" style="width: 32px; height: 32px;">
</button> <i class="bi bi-file-earmark-text"></i>
</form> </div>
<div class="bg-light" style="width: 2px; height: 35px; margin-top: 5px;"></div>
</div>
<div>
<h6 class="fw-bold text-dark mb-0">Registrasi Masuk</h6>
<small class="text-muted d-block mb-1">{{ $petani->created_at->format('d M Y, H:i') }}</small>
<span class="badge bg-light text-secondary border">Data Diterima</span>
</div>
</div>
{{-- STEP 2: MENUNGGU VERIFIKASI (Step Tengah) --}}
<div class="d-flex align-items-start mb-4">
<div class="d-flex flex-column align-items-center me-3">
{{-- Jika status menunggu, icon kuning. Jika sudah lewat (aktif/tolak), icon biru (selesai) --}}
@if($petani->status_akun == 'menunggu')
<div class="rounded-circle bg-warning text-dark d-flex align-items-center justify-content-center shadow-sm" style="width: 32px; height: 32px;">
<i class="bi bi-hourglass-split"></i>
</div>
<div class="bg-light" style="width: 2px; height: 35px; margin-top: 5px;"></div>
@else
<div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center shadow-sm" style="width: 32px; height: 32px;">
<i class="bi bi-check-lg"></i>
</div>
<div class="bg-light" style="width: 2px; height: 35px; margin-top: 5px;"></div>
@endif
</div>
<div>
<h6 class="fw-bold text-dark mb-0">Proses Verifikasi</h6>
@if($petani->status_akun == 'menunggu')
<small class="text-muted d-block mb-1">Sedang ditinjau...</small>
<span class="badge bg-warning text-dark bg-opacity-25">Pending</span>
@else
{{-- Jika sudah diproses, ambil waktunya --}}
<small class="text-muted d-block mb-1">{{ $petani->updated_at->format('d M Y, H:i') }}</small>
<span class="badge bg-light text-secondary border">Selesai Ditinjau</span>
@endif
</div>
</div>
{{-- STEP 3: HASIL AKHIR --}}
<div class="d-flex align-items-start">
<div class="d-flex flex-column align-items-center me-3">
@if($petani->status_akun == 'aktif')
<div class="rounded-circle bg-success text-white d-flex align-items-center justify-content-center shadow-sm" style="width: 32px; height: 32px;">
<i class="bi bi-shield-check"></i>
</div>
@elseif($petani->status_akun == 'ditolak')
<div class="rounded-circle bg-danger text-white d-flex align-items-center justify-content-center shadow-sm" style="width: 32px; height: 32px;">
<i class="bi bi-shield-x"></i>
</div>
@else
{{-- Icon abu-abu jika belum sampai tahap ini --}}
<div class="rounded-circle bg-light text-secondary border d-flex align-items-center justify-content-center" style="width: 32px; height: 32px;">
<i class="bi bi-question-lg"></i>
</div>
@endif
</div>
<div>
<h6 class="fw-bold text-dark mb-0">Keputusan Admin</h6>
@if($petani->status_akun == 'menunggu')
<small class="text-muted">Menunggu tindakan Anda...</small>
@elseif($petani->status_akun == 'aktif')
<small class="text-muted d-block mb-1">{{ $petani->updated_at->format('d M Y, H:i') }}</small>
<span class="badge bg-success bg-opacity-10 text-success">Disetujui</span>
@else
<small class="text-muted d-block mb-1">{{ $petani->updated_at->format('d M Y, H:i') }}</small>
<span class="badge bg-danger bg-opacity-10 text-danger">Ditolak</span>
@endif
</div>
</div>
<div class="mt-3">
<a href="{{ url('admin/verifikasi') }}" class="btn btn-secondary w-100">Kembali</a>
</div> </div>
<hr class="border-light my-3">
{{-- PANEL TOMBOL AKSI (Hanya muncul jika MENUNGGU) --}}
@if($petani->status_akun == 'menunggu')
<div class="mt-auto">
<div class="alert alert-warning border-0 d-flex align-items-center p-3 mb-3">
<i class="bi bi-info-circle-fill me-2 fs-5"></i>
<div class="small lh-sm">Pastikan data di samping valid sebelum memproses.</div>
</div>
<div class="d-grid gap-2">
<form action="{{ url('admin/verifikasi/'.$petani->id.'/approve') }}" method="POST">
@csrf
<button type="submit" class="btn btn-primary w-100 py-2 shadow-sm fw-bold" onclick="return confirm('Terima pendaftaran ini?')">
<i class="bi bi-check-circle-fill me-2"></i>Terima Pendaftaran
</button>
</form>
<form action="{{ url('admin/verifikasi/'.$petani->id.'/reject') }}" method="POST">
@csrf
<button type="submit" class="btn btn-outline-danger w-100 py-2 border-2 fw-bold" onclick="return confirm('Tolak pendaftaran ini?')">
<i class="bi bi-x-circle me-2"></i>Tolak Pendaftaran
</button>
</form>
</div>
</div>
@else
{{-- Pesan Status Akhir --}}
<div class="mt-auto text-center p-3 bg-light rounded border border-light">
<div class="fw-bold {{ $petani->status_akun == 'aktif' ? 'text-success' : 'text-danger' }}">
STATUS AKHIR: {{ strtoupper($petani->status_akun) }}
</div>
</div>
@endif
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="id"> <html lang="id">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -8,15 +9,60 @@
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" /> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" />
<style> <style>
body { background-color: #f0f7e6; height: 100vh; display: flex; align-items: center; justify-content: center; } body {
.card-auth { max-width: 400px; width: 100%; border: none; border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); } background-color: #f0f7e6;
.text-tani { color: #81c408; } height: 100vh;
.btn-tani { background-color: #81c408; border-color: #81c408; color: white; font-weight: bold; } display: flex;
.btn-tani:hover { background-color: #6da705; color: white; } align-items: center;
.form-control:focus { border-color: #81c408; box-shadow: 0 0 0 0.25rem rgba(129, 196, 8, 0.25); } justify-content: center;
.cursor-pointer { cursor: pointer; } }
.card-auth {
max-width: 400px;
width: 100%;
border: none;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05);
}
.text-tani {
color: #81c408;
}
.btn-tani {
background-color: #81c408;
border-color: #81c408;
color: white;
font-weight: bold;
}
.btn-tani:hover {
background-color: #6da705;
color: white;
}
.cursor-pointer {
cursor: pointer;
}
.form-control:focus {
box-shadow: none;
border-color: #ced4da;
}
.input-group:focus-within {
box-shadow: 0 0 0 0.25rem rgba(129, 196, 8, 0.25);
border-radius: 0.375rem;
z-index: 3;
}
.input-group:focus-within .input-group-text,
.input-group:focus-within .form-control {
border-color: #81c408;
}
</style> </style>
</head> </head>
<body> <body>
<div class="card card-auth bg-white p-4"> <div class="card card-auth bg-white p-4">
@ -28,33 +74,42 @@
<p class="text-muted small">Masuk untuk melanjutkan</p> <p class="text-muted small">Masuk untuk melanjutkan</p>
</div> </div>
@if(session('success')) <div class="alert alert-success py-2 small">{{ session('success') }}</div> @endif @if(session('success'))
@if($errors->any()) <div class="alert alert-danger py-2 small">{{ $errors->first() }}</div> @endif <div class="alert alert-success py-2 small">{{ session('success') }}</div> @endif
@if($errors->any())
<div class="alert alert-danger py-2 small">{{ $errors->first() }}</div> @endif
<form action="{{ route('login.proses') }}" method="POST"> <form action="{{ route('login.proses') }}" method="POST">
@csrf @csrf
<div class="mb-3"> <div class="mb-3">
<label class="form-label text-muted small">Username</label> <label class="form-label text-muted small">Username</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-text bg-white border-end-0 text-tani"><i class="fas fa-user"></i></span> <span class="input-group-text bg-white border-end-0 text-tani"><i
<input type="text" name="username" class="form-control border-start-0 ps-0" placeholder="Masukkan username" required> class="fas fa-user"></i></span>
<input type="text" name="username" class="form-control border-start-0 ps-0"
placeholder="Masukkan username" required>
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label text-muted small">Password</label> <label class="form-label text-muted small">Password</label>
<div class="input-group"> <div class="input-group">
<span class="input-group-text bg-white border-end-0 text-tani"><i class="fas fa-lock"></i></span> <span class="input-group-text bg-white border-end-0 text-tani"><i
<input type="password" name="password" id="password" class="form-control border-start-0 border-end-0 ps-0" placeholder="Masukkan password" required> class="fas fa-lock"></i></span>
<input type="password" name="password" id="password"
class="form-control border-start-0 border-end-0 ps-0" placeholder="Masukkan password"
required>
{{-- Icon Mata --}} {{-- Icon Mata --}}
<span class="input-group-text bg-white border-start-0 cursor-pointer" onclick="togglePassword('password', 'icon-pass')"> <span class="input-group-text bg-white border-start-0 cursor-pointer"
onclick="togglePassword('password', 'icon-pass')">
<i class="fas fa-eye text-muted" id="icon-pass"></i> <i class="fas fa-eye text-muted" id="icon-pass"></i>
</span> </span>
</div> </div>
</div> </div>
<div class="text-end mb-4"> <div class="text-end mb-4">
<a href="{{ route('password.request') }}" class="small text-muted text-decoration-none">Lupa Password?</a> <a href="{{ route('password.request') }}" class="small text-muted text-decoration-none">Lupa
Password?</a>
</div> </div>
<div class="d-grid gap-2"> <div class="d-grid gap-2">
@ -63,7 +118,8 @@
</form> </form>
<div class="text-center mt-4"> <div class="text-center mt-4">
<small class="text-muted">Belum punya akun? <a href="{{ route('register') }}" class="text-tani fw-bold text-decoration-none">Daftar</a></small> <small class="text-muted">Belum punya akun? <a href="{{ route('register') }}"
class="text-tani fw-bold text-decoration-none">Daftar</a></small>
</div> </div>
</div> </div>
</div> </div>
@ -86,4 +142,5 @@ function togglePassword(inputId, iconId) {
} }
</script> </script>
</body> </body>
</html> </html>

View File

@ -6,24 +6,22 @@
<div class="container py-5 mt-4"> <div class="container py-5 mt-4">
<h2 class="mb-4 fw-bold">Keranjang Belanja</h2> <h2 class="mb-4 fw-bold">Keranjang Belanja</h2>
{{-- Alert Notification --}} @if ($cart->count() > 0)
@if (session('success'))
<div class="alert alert-success alert-dismissible fade show shadow-sm" role="alert">
<i class="fa fa-check-circle me-2"></i> {{ session('success') }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
@endif
@if (count($cart) > 0)
<div class="row g-5"> <div class="row g-5">
<div class="col-lg-8"> <div class="col-lg-8">
<div class="card border-0 shadow-sm"> <div class="card border-0 shadow-sm">
<div class="card-body p-0"> <div class="card-body p-0">
<div class="table-responsive"> <div class="table-responsive">
<table class="table align-middle mb-0"> <table class="table align-middle mb-0">
<thead class="bg-light"> <thead class="border-bottom border-1">
<tr> <tr>
<th class="py-3 ps-4 border-0">Produk</th> {{-- CHECKBOX HEADER --}}
<th class="py-3 ps-4 border-0" style="width: 50px;">
<div class="form-check">
<input class="form-check-input cursor-pointer" type="checkbox" id="check-all" checked>
</div>
</th>
<th class="py-3 border-0">Produk</th>
<th class="py-3 border-0">Harga</th> <th class="py-3 border-0">Harga</th>
<th class="py-3 border-0">Jumlah</th> <th class="py-3 border-0">Jumlah</th>
<th class="py-3 border-0">Total</th> <th class="py-3 border-0">Total</th>
@ -32,50 +30,60 @@
</thead> </thead>
<tbody> <tbody>
@php $total_belanja = 0; @endphp @php $total_belanja = 0; @endphp
@foreach ($cart as $id => $details)
@foreach ($cart as $item)
@php @php
$total = $details['price'] * $details['quantity']; $total_per_item = $item->produk->harga * $item->quantity;
$total_belanja += $total; $total_belanja += $total_per_item;
@endphp @endphp
<tr data-id="{{ $id }}" class="border-bottom">
<td class="ps-4 py-3"> <tr data-id="{{ $item->id }}" class="border-bottom">
{{-- CHECKBOX ITEM --}}
<td class="ps-4 py-3 align-middle">
<div class="form-check">
<input class="form-check-input item-check cursor-pointer"
type="checkbox"
value="{{ $item->id }}"
data-subtotal="{{ $total_per_item }}"
checked>
</div>
</td>
<td class="py-3">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<img src="{{ $details['photo'] ? asset('storage/' . $details['photo']) : asset('template/frontend/img/vegetable-item-3.png') }}" <img src="{{ $item->produk->foto_produk ? asset('storage/' . $item->produk->foto_produk) : asset('template/frontend/img/vegetable-item-3.png') }}"
class="rounded-3 me-3" class="rounded-3 me-3"
style="width: 60px; height: 60px; object-fit: cover;"> style="width: 60px; height: 60px; object-fit: cover;">
<span class="fw-bold text-dark">{{ $details['name'] }}</span> <span class="fw-bold text-dark">{{ $item->produk->nama_produk }}</span>
</div> </div>
</td> </td>
<td class="text-muted">Rp <td class="text-muted">Rp
{{ number_format($details['price'], 0, ',', '.') }} {{ number_format($item->produk->harga, 0, ',', '.') }}
</td> </td>
<td class="align-middle text-center"> <td class="align-middle text-center">
<div class="input-group input-group-sm flex-nowrap mx-auto shadow-sm" <div class="input-group input-group-sm flex-nowrap mx-auto shadow-sm"
style="width: 120px;"> style="width: 120px;">
{{-- Tombol Minus --}}
<button class="btn btn-light border btn-minus-custom" type="button"> <button class="btn btn-light border btn-minus-custom" type="button">
<i class="fas fa-minus text-secondary" style="font-size: 0.8rem;"></i> <i class="fas fa-minus text-secondary" style="font-size: 0.8rem;"></i>
</button> </button>
{{-- Input Jumlah --}}
<input type="text" <input type="text"
class="form-control text-center border-top border-bottom border-light bg-white qty-input px-0" class="form-control text-center border-top border-bottom border-light bg-white qty-input px-0"
value="{{ $details['quantity'] }}" readonly style="min-width: 40px;"> value="{{ $item->quantity }}" readonly style="min-width: 40px;">
{{-- Tombol Plus --}}
<button class="btn btn-light border btn-plus-custom" type="button"> <button class="btn btn-light border btn-plus-custom" type="button">
<i class="fas fa-plus text-secondary" style="font-size: 0.8rem;"></i> <i class="fas fa-plus text-secondary" style="font-size: 0.8rem;"></i>
</button> </button>
</div> </div>
</td> </td>
<td class="fw-bold text-dark">Rp {{ number_format($total, 0, ',', '.') }} <td class="fw-bold text-dark">Rp {{ number_format($total_per_item, 0, ',', '.') }}
</td> </td>
<td class="pe-4 text-end"> <td class="pe-4 text-end">
<form action="{{ route('cart.remove') }}" method="POST" class="d-inline"> <form action="{{ route('cart.remove') }}" method="POST" class="d-inline">
@csrf @csrf
@method('DELETE') @method('DELETE')
<input type="hidden" name="id" value="{{ $id }}"> <input type="hidden" name="id" value="{{ $item->id }}">
<button class="btn btn-link text-danger p-0 text-decoration-none" <button class="btn btn-link text-danger p-0 text-decoration-none"
onclick="return confirm('Hapus item ini?')"> onclick="return confirm('Hapus item ini?')">
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
@ -97,16 +105,19 @@ class="form-control text-center border-top border-bottom border-light bg-white q
<h5 class="fw-bold mb-4">Ringkasan Belanja</h5> <h5 class="fw-bold mb-4">Ringkasan Belanja</h5>
<div class="d-flex justify-content-between mb-3"> <div class="d-flex justify-content-between mb-3">
<span class="text-muted">Subtotal</span> <span class="text-muted">Subtotal</span>
<span class="fw-bold">Rp {{ number_format($total_belanja, 0, ',', '.') }}</span> <span class="fw-bold" id="subtotal-display">Rp {{ number_format($total_belanja, 0, ',', '.') }}</span>
</div> </div>
<div class="d-flex justify-content-between mb-4 border-top pt-3"> <div class="d-flex justify-content-between mb-4 border-top pt-3">
<span class="fw-bold fs-5">Total</span> <span class="fw-bold fs-5">Total</span>
<span class="fw-bold fs-5 text-primary">Rp <span class="fw-bold fs-5 text-primary" id="total-display">Rp
{{ number_format($total_belanja, 0, ',', '.') }}</span> {{ number_format($total_belanja, 0, ',', '.') }}</span>
</div> </div>
<a href="{{ route('checkout') }}" class="btn btn-primary w-100 rounded-pill py-3 fw-bold shadow-sm">
{{-- Tombol Checkout Dinamis --}}
<a href="{{ route('checkout') }}" id="btn-checkout" class="btn btn-primary w-100 rounded-pill py-3 fw-bold shadow-sm">
Checkout Sekarang Checkout Sekarang
</a> </a>
<a href="{{ route('shop') }}" class="btn btn-link text-muted w-100 mt-2 text-decoration-none small"> <a href="{{ route('shop') }}" class="btn btn-link text-muted w-100 mt-2 text-decoration-none small">
Lanjut Belanja Lanjut Belanja
</a> </a>
@ -132,7 +143,8 @@ class="form-control text-center border-top border-bottom border-light bg-white q
@section('js') @section('js')
<script> <script>
$(document).ready(function () { $(document).ready(function () {
$(".quantity button").off("click"); // --- LOGIKA QUANTITY ---
$(".btn-plus-custom, .btn-minus-custom").off("click");
$(".btn-plus-custom").click(function (e) { $(".btn-plus-custom").click(function (e) {
e.preventDefault(); e.preventDefault();
@ -167,9 +179,61 @@ function updateCart(id, qty) {
}, },
success: function (response) { success: function (response) {
window.location.reload(); window.location.reload();
},
error: function(xhr) {
alert("Gagal update. Pastikan login.");
} }
}); });
} }
// --- LOGIKA CHECKBOX ---
const formatRupiah = (number) => {
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
maximumFractionDigits: 0
}).format(number).replace('Rp', 'Rp ');
}
function updateSummary() {
let total = 0;
let selectedIds = [];
$('.item-check:checked').each(function() {
total += parseFloat($(this).data('subtotal'));
selectedIds.push($(this).val());
});
$('#subtotal-display').text(formatRupiah(total));
$('#total-display').text(formatRupiah(total));
let baseUrl = "{{ route('checkout') }}";
let btn = $('#btn-checkout');
if(selectedIds.length === 0) {
btn.addClass('disabled');
btn.attr('href', '#');
} else {
btn.removeClass('disabled');
let newUrl = baseUrl + "?cart_ids=" + selectedIds.join(',');
btn.attr('href', newUrl);
}
}
$('#check-all').change(function() {
let isChecked = $(this).prop('checked');
$('.item-check').prop('checked', isChecked);
updateSummary();
});
$('.item-check').change(function() {
let allChecked = $('.item-check').length === $('.item-check:checked').length;
$('#check-all').prop('checked', allChecked);
updateSummary();
});
updateSummary();
}); });
</script> </script>
@endsection @endsection

View File

@ -177,48 +177,7 @@ class="btn btn-outline-dark rounded-pill py-2 border-2 fw-bold fs-6"
</div> </div>
<div class="row g-4"> <div class="row g-4">
@foreach ($produk_terkait as $produk) @include('landing.partials.product_list', ['produks' => $produk_terkait])
<div class="col-6 col-md-3">
<a href="{{ route('produk.detail', $produk->id) }}" class="text-decoration-none">
<div class="card border-0 shadow-sm h-100 product-card">
<!-- Stock Badge -->
<div class="position-absolute top-0 end-0 m-2 z-1">
<span class="badge bg-warning text-dark">
Stok: {{ $produk->stok }} Kg
</span>
</div>
<!-- Image -->
<div class="overflow-hidden" style="height: 200px;">
<img src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=800&auto=format&fit=crop' }}"
class="card-img-top w-100 h-100" alt="{{ $produk->nama_produk }}"
style="object-fit: cover;">
</div>
<div class="card-body d-flex justify-content-between flex-column p-3">
<div>
<span class="badge bg-success mb-2">{{ $produk->kategori ?? 'Umum' }}</span>
<h6 class="fw-bold mb-2">{{ $produk->nama_produk }}</h6>
<p class="text-muted small mb-3">{{ Str::limit($produk->deskripsi, 60) }}</p>
</div>
<div class="d-flex justify-content-between align-items-center pt-2 border-top">
<div>
<small class="text-muted">Harga/Kg</small>
<h6 class="fw-bold text-success mb-0">
Rp {{ number_format($produk->harga, 0, ',', '.') }}
</h6>
</div>
<a href="{{ route('produk.detail', $produk->id) }}"
class="btn btn-success btn-sm rounded-pill">
<i class="fa fa-eye"></i> Detail
</a>
</div>
</div>
</div>
</a>
</div>
@endforeach
</div> </div>
</div> </div>
@endif @endif

View File

@ -12,12 +12,12 @@
🌾 Mitra Petani Padi Indonesia 🌾 Mitra Petani Padi Indonesia
</div> </div>
<h1 class="display-4 fw-bold text-dark mb-4"> <h1 class="display-4 fw-bold text-dark mb-4">
Jual Gabah & <br> Pusat Jual Beli <br>
<span class="text-primary">Beras Berkualitas.</span> <span class="text-tani">Gabah Panen Raya.</span>
</h1> </h1>
<p class="lead text-muted mb-5"> <p class="lead text-muted mb-5">
Platform langsung yang menghubungkan petani padi lokal dengan pembeli. Platform langsung yang menghubungkan petani padi lokal dengan pembeli.
Dapatkan harga gabah terbaik dan beras segar tanpa pemutih. Dapatkan harga gabah terbaik dan gabah berkualitas.
</p> </p>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<a href="{{ route('shop') }}" class="btn btn-primary border-0 rounded-pill py-3 px-5 shadow"> <a href="{{ route('shop') }}" class="btn btn-primary border-0 rounded-pill py-3 px-5 shadow">
@ -30,9 +30,8 @@
</div> </div>
<div class="col-lg-6 order-1 order-lg-2 text-center"> <div class="col-lg-6 order-1 order-lg-2 text-center">
<div class="position-relative d-inline-block"> <div class="position-relative d-inline-block">
<img src="{{ asset('images/banner.jpg') }}" <img src="{{ asset('images/banner.jpg') }}" class="img-fluid rounded-circle shadow-lg w-100"
class="img-fluid rounded-circle shadow-lg w-100" style="max-height: 450px; object-fit: cover;" style="max-height: 450px; object-fit: cover;" alt="Padi Premium">
alt="Padi Premium">
<div class="position-absolute bg-white p-3 rounded-3 shadow d-none d-md-block" <div class="position-absolute bg-white p-3 rounded-3 shadow d-none d-md-block"
style="bottom: 30px; left: -30px;"> style="bottom: 30px; left: -30px;">
<div class="d-flex align-items-center gap-3"> <div class="d-flex align-items-center gap-3">
@ -81,7 +80,7 @@ class="img-fluid rounded-circle shadow-lg w-100" style="max-height: 450px; objec
<i class="fas fa-certificate fa-2x"></i> <i class="fas fa-certificate fa-2x"></i>
</div> </div>
<h5 class="fw-bold mb-3">Kualitas Super</h5> <h5 class="fw-bold mb-3">Kualitas Super</h5>
<p class="mb-0 text-muted">Jaminan beras pulen, wangi, dan bebas pemutih.</p> <p class="mb-0 text-muted">Jaminan padi berkualitas, bulir utuh, bersih, dan bebas campuran.</p>
</div> </div>
</div> </div>
<div class="col-md-6 col-lg-3"> <div class="col-md-6 col-lg-3">
@ -114,8 +113,7 @@ class="img-fluid w-100" style="height: 200px; object-fit: cover;"
alt="{{ $item->nama_produk }}"> alt="{{ $item->nama_produk }}">
</div> </div>
<div class="text-white bg-danger px-3 py-1 rounded position-absolute" <div class="text-white bg-danger px-3 py-1 rounded position-absolute" style="top: 10px; left: 10px;">
style="top: 10px; left: 10px;">
Terjual {{ $item->total_terjual ?? 0 }} Terjual {{ $item->total_terjual ?? 0 }}
</div> </div>
@ -149,7 +147,6 @@ class="btn btn-outline-primary rounded-pill px-3">
</div> </div>
</div> </div>
<div class="container-fluid py-5 bg-light"> <div class="container-fluid py-5 bg-light">
<div class="container"> <div class="container">
<div class="row g-5"> <div class="row g-5">
@ -181,19 +178,27 @@ class="btn btn-outline-primary rounded-pill px-3">
<div class="container py-5" id="katalog"> <div class="container py-5" id="katalog">
<div class="text-center mx-auto mb-5" style="max-width: 700px;"> <div class="text-center mx-auto mb-5" style="max-width: 700px;">
<h2 class="fw-bold display-6 text-dark">Stok Gudang Kami</h2> <h2 class="fw-bold display-6 text-dark">Stok Gudang Kami</h2>
<p class="text-muted">Pilih varietas padi atau beras yang Anda butuhkan hari ini.</p> <p class="text-muted">Pilih varietas gabah yang Anda butuhkan hari ini.</p>
</div> </div>
@php
$kategoriList = \App\Models\Kategori::all();
@endphp
<div class="row justify-content-center mb-5"> <div class="row justify-content-center mb-5">
<div class="col-12 text-center"> <div class="col-12 text-center">
@php $kategoris = ['Semua', 'Pandan Wangi', 'IR 64', 'Ketan', 'Merah', 'Hitam']; @endphp
<div class="d-flex justify-content-center flex-wrap gap-2"> <div class="d-flex justify-content-center flex-wrap gap-2">
@foreach ($kategoris as $kategori) <a href="#" data-kategori="Semua"
<button class="btn {{ request('kategori') == '' || request('kategori') == 'Semua' ? 'btn-primary' : 'btn-outline-primary' }} rounded-pill px-4 py-2 m-1 btn-category">
class="btn {{ $loop->first ? 'btn-primary' : 'btn-outline-primary' }} rounded-pill px-4 py-2 m-1 btn-category" Semua
data-kategori="{{ $kategori }}"> </a>
{{ $kategori }}
</button> {{-- 2. Looping Kategori dari Database --}}
@foreach($kategoriList as $kat)
<a href="#" data-kategori="{{ $kat->slug }}"
class="btn {{ request('kategori') == $kat->slug ? 'btn-primary' : 'btn-outline-primary' }} rounded-pill px-4 py-2 m-1 btn-category">
<span>{{ $kat->nama_kategori }}</span>
</a>
@endforeach @endforeach
</div> </div>
</div> </div>
@ -235,13 +240,16 @@ class="btn btn-light rounded-pill px-5 py-3 text-success fw-bold shadow">
@section('js') @section('js')
<script> <script>
$(document).ready(function() { $(document).ready(function () {
$('.btn-category').click(function(e) { $('.btn-category').click(function (e) {
e.preventDefault(); e.preventDefault();
let kategori = $(this).data('kategori'); let kategori = $(this).data('kategori');
$('.btn-category').removeClass('btn-primary').addClass('btn-outline-primary'); $('.btn-category').removeClass('btn-primary').addClass('btn-outline-primary');
$(this).removeClass('btn-outline-primary').addClass('btn-primary'); $(this).removeClass('btn-outline-primary').addClass('btn-primary');
// Tampilkan loading
$('#product-container').html( $('#product-container').html(
'<div class="col-12 text-center py-5">' + '<div class="col-12 text-center py-5">' +
'<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status"></div>' + '<div class="spinner-border text-primary" style="width: 3rem; height: 3rem;" role="status"></div>' +
@ -249,16 +257,17 @@ class="btn btn-light rounded-pill px-5 py-3 text-success fw-bold shadow">
'</div>' '</div>'
); );
// Kirim request AJAX
$.ajax({ $.ajax({
url: "{{ route('home') }}", url: "{{ route('home') }}",
type: "GET", type: "GET",
data: { data: {
kategori: kategori kategori: kategori
}, },
success: function(response) { success: function (response) {
$('#product-container').html(response); $('#product-container').html(response);
}, },
error: function(xhr) { error: function (xhr) {
$('#product-container').html( $('#product-container').html(
'<div class="col-12 text-center text-danger">Gagal memuat data.</div>' '<div class="col-12 text-center text-danger">Gagal memuat data.</div>'
); );

View File

@ -1,45 +1,39 @@
@forelse($produks as $produk) @forelse($produks as $produk)
<div class="col-md-6 col-lg-4 col-xl-3 mb-4"> <div class="col-md-6 col-lg-4">
<div class="card h-100 product-card"> <div class="card border-0 shadow-sm h-100 product-card position-relative">
<div class="position-absolute top-0 start-0 m-3 z-1"> <div class="position-absolute top-0 end-0 m-2 z-2">
<span class="badge bg-white text-success shadow-sm"> <span class="badge bg-warning text-dark shadow-sm">
<i class="fas fa-leaf me-1"></i> {{ $produk->kategori ?? 'Padi' }}
</span>
</div>
<div class="position-absolute top-0 end-0 m-3 z-1">
<span class="badge bg-warning text-dark shadow-sm">
Stok: {{ $produk->stok }} Kg Stok: {{ $produk->stok }} Kg
</span> </span>
</div> </div>
<div class="ratio ratio-4x3 overflow-hidden bg-light"> <div class="overflow-hidden bg-light position-relative" style="height: 200px;">
<img src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=800&auto=format&fit=crop' }}" <img src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=800&auto=format&fit=crop' }}"
class="card-img-top object-fit-cover" alt="{{ $produk->nama_produk }}"> class="card-img-top w-100 h-100 object-fit-cover" alt="{{ $produk->nama_produk }}">
</div> </div>
<div class="card-body d-flex flex-column p-4"> <div class="card-body d-flex justify-content-between flex-column p-3">
<small class="text-muted mb-1"> <div>
<i class="fas fa-user-circle me-1"></i> {{ Str::limit($produk->petani->nama_lengkap ?? 'Petani Lokal', 15) }} <span class="badge bg-primary mb-2">
</small> {{ $produk->kategori->nama_kategori ?? 'Umum' }}
</span>
<h5 class="fw-bold text-dark mb-2 text-truncate" title="{{ $produk->nama_produk }}"> <h5 class="fw-bold mb-2 text-dark">{{ $produk->nama_produk }}</h5>
{{ $produk->nama_produk }}
</h5>
<p class="text-secondary small mb-3 flex-grow-1" style="line-height: 1.5;"> <p class="text-muted small mb-3" style="line-height: 1.5;">
{{ Str::limit($produk->deskripsi, 60) }} {{ Str::limit($produk->deskripsi, 60) }}
</p> </p>
</div>
<div class="d-flex justify-content-between align-items-end mt-3 border-top pt-3"> <div class="d-flex justify-content-between align-items-center pt-3 border-top mt-auto">
<div> <div>
<small class="text-muted d-block" style="font-size: 0.8rem;">Harga per Kg</small> <small class="text-muted d-block" style="font-size: 0.8rem;">Harga/Kg</small>
<h5 class="fw-bold text-success mb-0"> <h6 class="fw-bold text-primary mb-0">
Rp {{ number_format($produk->harga, 0, ',', '.') }} Rp {{ number_format($produk->harga, 0, ',', '.') }}
</h5> </h6>
</div> </div>
<a href="{{ route('produk.detail', $produk->id) }}" <a href="{{ route('produk.detail', $produk->id) }}"
class="btn btn-outline-success btn-sm stretched-link"> class="btn btn-primary btn-sm rounded-pill px-3 stretched-link">
Lihat <i class="fa fa-arrow-right ms-1"></i> Lihat <i class="fa fa-arrow-right ms-1"></i>
</a> </a>
</div> </div>
@ -48,15 +42,13 @@ class="btn btn-outline-success btn-sm stretched-link">
</div> </div>
@empty @empty
<div class="col-12"> <div class="col-12">
<div class="text-center py-5"> <div class="text-center py-5 bg-white rounded-3 shadow-sm border border-dashed">
<div class="mb-3"> <i class="fas fa-search fa-3x text-muted opacity-25 mb-3"></i>
<i class="fas fa-seedling fa-4x text-muted opacity-50"></i> <h5 class="fw-bold text-dark">Belum ada stok gabah tersedia.</h5>
</div> <p class="text-muted mb-4">Silakan cek kembali saat musim panen tiba atau reset filter pencarian Anda.</p>
<h4 class="text-muted fw-bold">Belum Ada Panen</h4> <a href="{{ route('shop') }}" class="btn btn-outline-primary rounded-pill px-4">
<p class="text-secondary">Produk kategori ini sedang tidak tersedia.</p> <i class="fas fa-sync-alt me-2"></i> Reset Filter
<button class="btn btn-primary mt-2" onclick="location.reload()"> </a>
Refresh Halaman
</button>
</div> </div>
</div> </div>
@endforelse @endforelse

View File

@ -1,55 +1,127 @@
@extends('layouts.frontend') @extends('layouts.frontend')
@section('title', 'Pesan Saya') @section('title', 'Pesan Saya')
@section('css')
<style>
/* Layout Utama Chat */
.chat-layout {
height: 60vh;
background-color: #fff;
border: 1px solid #dee2e6;
border-radius: 12px;
overflow: hidden;
}
/* --- Sidebar Kiri --- */
.chat-sidebar {
height: 100%;
background-color: #fff;
border-right: 1px solid #dee2e6;
display: flex;
flex-direction: column;
}
/* Header Pencarian */
.sidebar-header {
padding: 15px;
border-bottom: 1px solid #f0f0f0;
}
/* List User Scrollable */
.chat-list-container {
flex-grow: 1;
overflow-y: auto;
}
/* Item Chat */
.chat-item {
transition: all 0.2s;
border-bottom: 1px solid #f8f9fa;
cursor: pointer;
}
.chat-item:hover {
background-color: #f9fdf0;
border-left: 4px solid #81c408;
}
/* --- Area Kanan --- */
.chat-placeholder {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f8f9fa;
color: #adb5bd;
}
/* Custom Scrollbar */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #ccc; border-radius: 10px; }
</style>
@endsection
@section('content') @section('content')
<div class="container py-5"> <div class="container py-5">
<h2 class="mb-4 fw-bold text-dark">Pesan Saya</h2> <h2 class="mb-4 fw-bold text-dark">Pesan Saya</h2>
<div class="row g-0 chat-container"> {{-- Container Utama --}}
<div class="row g-0 chat-layout shadow-sm">
{{-- KOLOM KIRI: DAFTAR PESAN --}}
<div class="col-md-4 chat-sidebar"> <div class="col-md-4 chat-sidebar">
<div class="p-3 bg-white sticky-top border-bottom"> <div class="sidebar-header">
<input type="text" class="form-control rounded-pill" placeholder="Cari pesan..."> <input type="text" class="form-control bg-light border-0 rounded-pill px-3" placeholder="Cari pesan...">
</div> </div>
<div class="list-group list-group-flush"> <div class="chat-list-container">
@forelse($chatList as $chat) <div class="list-group list-group-flush">
<a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}" @forelse($chatList as $chat)
class="list-group-item list-group-item-action chat-list-item py-3"> <a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}"
<div class="d-flex align-items-center"> class="list-group-item list-group-item-action chat-item py-3 border-0">
<div class="position-relative"> <div class="d-flex align-items-center">
<img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle" {{-- Avatar --}}
width="50" height="50" style="object-fit: cover;"> <div class="position-relative">
@if ($chat['unread'] > 0) <img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle shadow-sm"
<span width="50" height="50" style="object-fit: cover;">
class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"> @if ($chat['unread'] > 0)
{{ $chat['unread'] }} <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger border border-white">
</span> {{ $chat['unread'] }}
@endif </span>
</div> @endif
<div class="ms-3 flex-grow-1 overflow-hidden"> </div>
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0 text-dark fw-bold text-truncate">{{ $chat['nama'] }}</h6> {{-- Info Pesan --}}
<small class="text-muted" style="font-size: 0.75rem;">{{ $chat['time'] }}</small> <div class="ms-3 flex-grow-1 overflow-hidden">
<div class="d-flex justify-content-between align-items-center mb-1">
<h6 class="mb-0 text-dark fw-bold text-truncate">{{ $chat['nama'] }}</h6>
<small class="text-muted" style="font-size: 0.75rem;">{{ $chat['time'] }}</small>
</div>
<p class="mb-0 text-muted text-truncate small">
{{ Str::limit($chat['last_message'], 35) }}
</p>
</div> </div>
<p class="mb-0 text-muted text-truncate small">
{{ Str::limit($chat['last_message'], 35) }}
</p>
</div> </div>
</a>
@empty
<div class="text-center py-5 px-3">
<i class="far fa-comment-dots fa-3x text-muted mb-3 opacity-50"></i>
<p class="text-muted small">Belum ada percakapan.</p>
</div> </div>
</a> @endforelse
@empty </div>
<div class="text-center py-5 px-3">
<p class="text-muted">Belum ada percakapan.</p>
</div>
@endforelse
</div> </div>
</div> </div>
<div class="col-md-8 d-none d-md-flex flex-column align-items-center justify-content-center bg-white"> {{-- KOLOM KANAN: PLACEHOLDER --}}
<div class="text-center opacity-50"> <div class="col-md-8 d-none d-md-flex chat-placeholder">
<i class="fa fa-comments fa-4x text-success mb-3"></i> <div class="text-center">
<h5>Selamat Datang di Chat</h5> <div class="bg-white p-4 rounded-circle shadow-sm d-inline-block mb-3">
<p>Pilih salah satu percakapan di sebelah kiri<br>untuk melihat detail pesan.</p> <i class="fas fa-comments fa-4x text-success"></i>
</div>
<h5 class="fw-bold text-dark">Selamat Datang di Chat</h5>
<p class="small">Pilih salah satu percakapan di sebelah kiri<br>untuk mulai berdiskusi dengan Petani.</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,136 +1,120 @@
@extends('layouts.frontend') @extends('layouts.frontend')
@section('title', 'Chat dengan ' . $lawan->nama_lengkap) @section('title', 'Chat dengan ' . $lawan->nama_lengkap)
@section('css')
<style>
/* Layout Utama */
.chat-layout {
height: 60vh;
background-color: #fff;
border: 1px solid #dee2e6;
border-radius: 12px;
overflow: hidden;
}
/* --- Sidebar Kiri --- */
.chat-sidebar {
background-color: #fff;
border-right: 1px solid #dee2e6 !important;
height: 100%;
display: flex;
flex-direction: column;
}
.chat-item {
transition: all 0.2s;
border-bottom: 1px solid #f8f9fa;
cursor: pointer;
}
.chat-item:hover, .chat-item.active {
background-color: #f9fdf0;
border-left: 4px solid #81c408;
}
/* --- Area Chat Kanan --- */
.chat-main {
background-color: #ffffff;
display: flex;
flex-direction: column;
height: 100%;
}
.chat-header {
padding: 15px 20px;
background: #fff;
border-bottom: 1px solid #dee2e6;
z-index: 10;
}
.chat-content {
flex-grow: 1;
overflow-y: auto;
padding: 25px;
background-image: url('https://www.transparenttextures.com/patterns/subtle-white-feathers.png');*/
background-color: #f8f9fa;
display: flex;
flex-direction: column;
gap: 15px;
}
/* Bubble Chat */
.chat-bubble {
max-width: 75%;
padding: 12px 18px;
position: relative;
font-size: 0.95rem;
line-height: 1.5;
border-radius: 18px;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.bubble-me {
background-color: #81c408;
color: #fff;
align-self: flex-end;
border-bottom-right-radius: 4px;
}
.bubble-other {
background-color: #fff;
border: 1px solid #e9ecef;
color: #333;
align-self: flex-start;
border-bottom-left-radius: 4px;
}
.chat-time {
font-size: 0.7rem;
margin-top: 4px;
display: block;
text-align: right;
opacity: 0.75;
}
.chat-footer {
padding: 15px 20px;
background: #fff;
border-top: 1px solid #dee2e6;
}
/* Scrollbar */
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #ccc; border-radius: 10px; }
</style>
@endsection
@section('content') @section('content')
<style>
.chat-layout {
height: 80vh;
background-color: #fff;
border: 1px solid #e9ecef;
border-radius: 12px;
overflow: hidden;
}
/* --- Sidebar Kiri (List User) --- */
.chat-sidebar {
background-color: #fff;
border-right: 1px solid #f0f0f0;
height: 100%;
display: flex;
flex-direction: column;
}
.chat-item {
transition: all 0.2s;
border-bottom: 1px solid #f8f9fa;
}
.chat-item:hover,
.chat-item.active {
background-color: #f9fdf0;
border-left: 4px solid #81c408;
}
/* --- Area Chat Kanan --- */
.chat-main {
background-color: #ffffff;
display: flex;
flex-direction: column;
height: 100%;
}
.chat-header {
padding: 15px 20px;
background: #fff;
border-bottom: 1px solid #f0f0f0;
}
.chat-content {
flex-grow: 1;
overflow-y: auto;
padding: 25px;
background-color: #fafafa;
display: flex;
flex-direction: column;
gap: 15px;
}
/* --- Bubble Chat Style --- */
.chat-bubble {
max-width: 75%;
padding: 12px 18px;
position: relative;
font-size: 0.95rem;
line-height: 1.5;
border-radius: 18px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03);
}
/* Pesan SAYA */
.bubble-me {
background-color: #81c408;
color: #ffffff;
align-self: flex-end;
border-bottom-right-radius: 4px;
}
/* Pesan LAWAN */
.bubble-other {
background-color: #f1f3f5;
color: #333333;
align-self: flex-start;
border-bottom-left-radius: 4px;
}
.chat-time {
font-size: 0.7rem;
margin-top: 4px;
display: block;
text-align: right;
opacity: 0.7;
}
.chat-footer {
padding: 15px 20px;
background: #fff;
border-top: 1px solid #f0f0f0;
}
.btn-send {
background-color: #81c408;
color: white;
border: none;
transition: 0.3s;
}
.btn-send:hover {
background-color: #6da705;
color: white;
}
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 10px;
}
</style>
<div class="container py-5"> <div class="container py-5">
<div class="row g-0 chat-layout shadow-sm"> <div class="row g-0 chat-layout shadow-lg">
{{-- SIDEBAR KIRI --}} {{-- SIDEBAR KIRI --}}
<div class="col-md-4 chat-sidebar d-none d-md-flex"> <div class="col-md-4 chat-sidebar d-none d-md-flex">
{{-- Header Sidebar --}} {{-- Header Sidebar --}}
<div class="p-3 border-bottom"> <div class="p-3 border-bottom">
<h6 class="fw-bold text-dark mb-3">Pesan Masuk</h6> <h6 class="fw-bold text-dark mb-3">Pesan Masuk</h6>
<input type="text" class="form-control bg-light border-0 rounded-pill" placeholder="Cari percakapan..."> <input type="text" class="form-control bg-light border-0 rounded-pill px-3" placeholder="Cari percakapan...">
</div> </div>
{{-- List Chat --}} {{-- List Chat --}}
@ -139,13 +123,10 @@
<a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}" <a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}"
class="d-flex align-items-center p-3 text-decoration-none text-dark chat-item {{ $chat['lawan_id'] == $lawan->id ? 'active' : '' }}"> class="d-flex align-items-center p-3 text-decoration-none text-dark chat-item {{ $chat['lawan_id'] == $lawan->id ? 'active' : '' }}">
{{-- Avatar --}}
<div class="position-relative"> <div class="position-relative">
<img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle" width="45" <img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle shadow-sm" width="45" height="45" style="object-fit: cover;">
height="45" style="object-fit: cover;">
@if($chat['unread'] > 0) @if($chat['unread'] > 0)
<span <span class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border border-light rounded-circle"></span>
class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border border-light rounded-circle"></span>
@endif @endif
</div> </div>
@ -159,8 +140,7 @@ class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border b
{{ Str::limit($chat['last_message'], 25) }} {{ Str::limit($chat['last_message'], 25) }}
</p> </p>
@if($chat['unread'] > 0) @if($chat['unread'] > 0)
<span class="badge bg-danger rounded-pill" <span class="badge bg-danger rounded-pill" style="font-size: 0.6rem;">{{ $chat['unread'] }}</span>
style="font-size: 0.6rem;">{{ $chat['unread'] }}</span>
@endif @endif
</div> </div>
</div> </div>
@ -172,14 +152,12 @@ class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border b
{{-- AREA CHAT KANAN --}} {{-- AREA CHAT KANAN --}}
<div class="col-md-8 chat-main"> <div class="col-md-8 chat-main">
{{-- Header Chat --}} {{-- Header Chat --}}
<div class="chat-header d-flex align-items-center justify-content-between"> <div class="chat-header d-flex align-items-center justify-content-between">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<a href="{{ route('pembeli.pesan.index') }}" class="d-md-none me-3 text-dark"><i <a href="{{ route('pembeli.pesan.index') }}" class="d-md-none me-3 text-dark"><i class="fas fa-arrow-left"></i></a>
class="fas fa-arrow-left"></i></a>
{{-- Inisial Nama Lawan --}} <div class="rounded-circle d-flex align-items-center justify-content-center fw-bold text-white me-3 shadow-sm"
<div class="rounded-circle d-flex align-items-center justify-content-center fw-bold text-white me-3"
style="width: 40px; height: 40px; background-color: #81c408; font-size: 1.1rem;"> style="width: 40px; height: 40px; background-color: #81c408; font-size: 1.1rem;">
{{ substr($lawan->nama_lengkap, 0, 1) }} {{ substr($lawan->nama_lengkap, 0, 1) }}
</div> </div>
@ -205,22 +183,17 @@ class="fas fa-arrow-left"></i></a>
$isMe = ($chat->pengirim_id == $currentUser->id) && ($chat->pengirim_type == $currentUserType); $isMe = ($chat->pengirim_id == $currentUser->id) && ($chat->pengirim_type == $currentUserType);
@endphp @endphp
{{-- BUBBLE CHAT --}}
<div class="chat-bubble {{ $isMe ? 'bubble-me' : 'bubble-other' }}"> <div class="chat-bubble {{ $isMe ? 'bubble-me' : 'bubble-other' }}">
{{ $chat->isi_pesan }} {{ $chat->isi_pesan }}
<span class="chat-time"> <span class="chat-time {{ $isMe ? 'text-white-50' : 'text-muted' }}">
{{ $chat->created_at->format('H:i') }} {{ $chat->created_at->format('H:i') }}
@if ($isMe) @if ($isMe) <i class="fas fa-check ms-1" style="font-size: 0.6rem;"></i> @endif
<i class="fas fa-check ms-1" style="font-size: 0.6rem;"></i>
@endif
</span> </span>
</div> </div>
@empty @empty
<div class="text-center mt-5 opacity-50"> <div class="text-center mt-5 opacity-50">
<i class="far fa-comments fa-3x mb-3 text-secondary"></i> <i class="far fa-comments fa-3x mb-3 text-secondary"></i>
<p class="small text-muted">Belum ada percakapan.<br>Sapa <p class="small text-muted">Mulai percakapan dengan<br><strong>{{ $lawan->nama_lengkap }}</strong></p>
<strong>{{ $lawan->nama_lengkap }}</strong> sekarang!</p>
</div> </div>
@endforelse @endforelse
</div> </div>
@ -233,11 +206,10 @@ class="fas fa-arrow-left"></i></a>
<input type="hidden" name="penerima_type" value="{{ get_class($lawan) }}"> <input type="hidden" name="penerima_type" value="{{ get_class($lawan) }}">
<input type="text" name="isi_pesan" class="form-control bg-light border-0 rounded-pill px-4 py-2" <input type="text" name="isi_pesan" class="form-control bg-light border-0 rounded-pill px-4 py-2"
placeholder="Tulis pesan Anda..." required autocomplete="off"> placeholder="Tulis pesan..." required autocomplete="off">
<button type="submit" <button type="submit" class="btn btn-success rounded-circle d-flex align-items-center justify-content-center shadow-sm"
class="btn btn-send rounded-circle d-flex align-items-center justify-content-center shadow-sm" style="width: 42px; height: 42px; background-color: #81c408; border: none;">
style="width: 45px; height: 45px;">
<i class="fas fa-paper-plane"></i> <i class="fas fa-paper-plane"></i>
</button> </button>
</form> </form>
@ -251,7 +223,6 @@ class="btn btn-send rounded-circle d-flex align-items-center justify-content-cen
@section('js') @section('js')
<script> <script>
$(document).ready(function () { $(document).ready(function () {
// Auto scroll ke bawah
const chatBox = document.getElementById("chatBox"); const chatBox = document.getElementById("chatBox");
if (chatBox) { if (chatBox) {
chatBox.scrollTop = chatBox.scrollHeight; chatBox.scrollTop = chatBox.scrollHeight;

View File

@ -10,9 +10,6 @@
<h2 class="fw-bold text-dark mb-0">Riwayat Pesanan</h2> <h2 class="fw-bold text-dark mb-0">Riwayat Pesanan</h2>
<p class="text-muted small mb-0">Pantau status belanjaan Anda di sini</p> <p class="text-muted small mb-0">Pantau status belanjaan Anda di sini</p>
</div> </div>
<a href="{{ route('shop') }}" class="btn btn-primary rounded-pill px-4 shadow-sm">
<i class="fas fa-shopping-bag me-2"></i>Belanja Lagi
</a>
</div> </div>

View File

@ -3,6 +3,7 @@
@section('title', 'Belanja Padi & Beras') @section('title', 'Belanja Padi & Beras')
@section('content') @section('content')
{{-- Header Halaman --}}
<div class="container-fluid py-5 bg-light border-bottom mb-5"> <div class="container-fluid py-5 bg-light border-bottom mb-5">
<div class="container text-center"> <div class="container text-center">
<h1 class="display-5 fw-bold text-dark mb-3">Belanja Produk Kami</h1> <h1 class="display-5 fw-bold text-dark mb-3">Belanja Produk Kami</h1>
@ -15,30 +16,14 @@
</div> </div>
</div> </div>
{{-- Konten Utama --}}
<div class="container pb-5"> <div class="container pb-5">
<div class="row g-4"> <div class="row g-4">
{{-- SIDEBAR FILTER --}}
<div class="col-lg-3"> <div class="col-lg-3">
<div class="card border-0 shadow-sm mb-4"> {{-- Card Kategori --}}
<div class="card-body p-4">
<h6 class="fw-bold mb-3 text-uppercase small text-muted">Cari Produk</h6>
<form action="{{ route('shop') }}" method="GET">
@if(request('kategori')) <input type="hidden" name="kategori" value="{{ request('kategori') }}">
@endif
@if(request('sort')) <input type="hidden" name="sort" value="{{ request('sort') }}"> @endif
<div class="input-group">
<input type="search" name="search" class="form-control bg-light border-0"
placeholder="Nama produk..." value="{{ request('search') }}">
<button class="btn btn-primary" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</form>
</div>
</div>
<div class="card border-0 shadow-sm mb-4"> <div class="card border-0 shadow-sm mb-4">
<div class="card-body p-4"> <div class="card-body p-4">
<h6 class="fw-bold mb-3 text-uppercase small text-muted">Kategori</h6> <h6 class="fw-bold mb-3 text-uppercase small text-muted">Kategori</h6>
@ -49,12 +34,13 @@
$currentKat = request('kategori'); $currentKat = request('kategori');
@endphp @endphp
{{-- Tombol Semua Kategori --}}
<a href="{{ route('shop', array_merge(request()->query(), ['kategori' => null])) }}" <a href="{{ route('shop', array_merge(request()->query(), ['kategori' => null])) }}"
class="d-flex justify-content-between align-items-center text-decoration-none {{ !$currentKat ? 'fw-bold text-primary' : 'text-secondary' }}"> class="d-flex justify-content-between align-items-center text-decoration-none {{ !$currentKat ? 'fw-bold text-primary' : 'text-secondary' }}">
<span>Semua Kategori</span> <span>Semua Kategori</span>
</a> </a>
{{-- Looping Data Database --}} {{-- Looping Kategori Database --}}
@foreach($kategoriList as $kat) @foreach($kategoriList as $kat)
<a href="{{ route('shop', array_merge(request()->query(), ['kategori' => $kat->slug])) }}" <a href="{{ route('shop', array_merge(request()->query(), ['kategori' => $kat->slug])) }}"
class="d-flex justify-content-between align-items-center text-decoration-none {{ $currentKat == $kat->slug ? 'fw-bold text-primary' : 'text-secondary' }}"> class="d-flex justify-content-between align-items-center text-decoration-none {{ $currentKat == $kat->slug ? 'fw-bold text-primary' : 'text-secondary' }}">
@ -71,6 +57,7 @@ class="d-flex justify-content-between align-items-center text-decoration-none {{
</div> </div>
</div> </div>
{{-- Banner Info Kecil --}}
<div class="card border-0 shadow-sm bg-primary text-white"> <div class="card border-0 shadow-sm bg-primary text-white">
<div class="card-body p-4"> <div class="card-body p-4">
<h5 class="fw-bold mb-2"><i class="fas fa-leaf me-2"></i>Produk Segar</h5> <h5 class="fw-bold mb-2"><i class="fas fa-leaf me-2"></i>Produk Segar</h5>
@ -80,19 +67,20 @@ class="d-flex justify-content-between align-items-center text-decoration-none {{
</div> </div>
</div> </div>
{{-- LIST PRODUK --}}
<div class="col-lg-9"> <div class="col-lg-9">
{{-- Top Bar (Info Jumlah & Sorting) --}}
<div class="d-flex justify-content-between align-items-center mb-4 bg-white p-3 rounded shadow-sm border"> <div class="d-flex justify-content-between align-items-center mb-4 bg-white p-3 rounded shadow-sm border">
<div class="d-none d-md-block text-muted small"> <div class="d-none d-md-block text-muted small">
Menampilkan <span Menampilkan <span class="fw-bold text-dark">{{ $produks->firstItem() ?? 0 }}-{{ $produks->lastItem() ?? 0 }}</span>
class="fw-bold text-dark">{{ $produks->firstItem() ?? 0 }}-{{ $produks->lastItem() ?? 0 }}</span>
dari <span class="fw-bold text-dark">{{ $produks->total() }}</span> produk dari <span class="fw-bold text-dark">{{ $produks->total() }}</span> produk
</div> </div>
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<label class="small text-muted me-2 text-nowrap">Urutkan:</label> <label class="small text-muted me-2 text-nowrap">Urutkan:</label>
<form id="sortForm" action="{{ route('shop') }}" method="GET"> <form id="sortForm" action="{{ route('shop') }}" method="GET">
{{-- Pertahankan query lain saat sorting --}} {{-- Pertahankan query lain (search/kategori) saat sorting --}}
@foreach(request()->except('sort') as $key => $value) @foreach(request()->except('sort') as $key => $value)
<input type="hidden" name="{{ $key }}" value="{{ $value }}"> <input type="hidden" name="{{ $key }}" value="{{ $value }}">
@endforeach @endforeach
@ -113,19 +101,18 @@ class="fw-bold text-dark">{{ $produks->firstItem() ?? 0 }}-{{ $produks->lastItem
</div> </div>
</div> </div>
{{-- Grid Produk --}}
<div class="row g-4"> <div class="row g-4">
@forelse($produks as $produk) @forelse($produks as $produk)
<div class="col-md-6 col-lg-4"> <div class="col-md-6 col-lg-4">
<a href="{{ route('produk.detail', $produk->id) }}" class="text-decoration-none"> <a href="{{ route('produk.detail', $produk->id) }}" class="text-decoration-none">
<div class="card border-0 shadow-sm h-100 product-card"> <div class="card border-0 shadow-sm h-100 product-card">
<!-- Stock Badge -->
<div class="position-absolute top-0 end-0 m-2 z-1"> <div class="position-absolute top-0 end-0 m-2 z-1">
<span class="badge bg-warning text-dark"> <span class="badge bg-warning text-dark">
Stok: {{ $produk->stok }} Kg Stok: {{ $produk->stok }} Kg
</span> </span>
</div> </div>
<!-- Image -->
<div class="overflow-hidden" style="height: 200px;"> <div class="overflow-hidden" style="height: 200px;">
<img src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=800&auto=format&fit=crop' }}" <img src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=800&auto=format&fit=crop' }}"
class="card-img-top w-100 h-100" alt="{{ $produk->nama_produk }}" class="card-img-top w-100 h-100" alt="{{ $produk->nama_produk }}"
@ -134,22 +121,21 @@ class="card-img-top w-100 h-100" alt="{{ $produk->nama_produk }}"
<div class="card-body d-flex justify-content-between flex-column p-3"> <div class="card-body d-flex justify-content-between flex-column p-3">
<div> <div>
<span class="badge bg-success mb-2">{{ $produk->kategori->nama_kategori ?? 'Umum' }}</span> <span class="badge bg-primary mb-2">{{ $produk->kategori->nama_kategori ?? 'Umum' }}</span>
<h6 class="fw-bold mb-2">{{ $produk->nama_produk }}</h6> <h6 class="fw-bold mb-2 text-dark">{{ $produk->nama_produk }}</h6>
<p class="text-muted small mb-3">{{ Str::limit($produk->deskripsi, 60) }}</p> <p class="text-muted small mb-3">{{ Str::limit($produk->deskripsi, 60) }}</p>
</div> </div>
<div class="d-flex justify-content-between align-items-center pt-2 border-top"> <div class="d-flex justify-content-between align-items-center pt-2 border-top">
<div> <div>
<small class="text-muted">Harga/Kg</small> <small class="text-muted">Harga/Kg</small>
<h6 class="fw-bold text-success mb-0"> <h6 class="fw-bold text-primary mb-0">
Rp {{ number_format($produk->harga, 0, ',', '.') }} Rp {{ number_format($produk->harga, 0, ',', '.') }}
</h6> </h6>
</div> </div>
<a href="{{ route('produk.detail', $produk->id) }}" <button class="btn btn-primary btn-sm rounded-pill">
class="btn btn-success btn-sm rounded-pill">
<i class="fa fa-eye"></i> Detail <i class="fa fa-eye"></i> Detail
</a> </button>
</div> </div>
</div> </div>
</div> </div>
@ -169,6 +155,7 @@ class="btn btn-success btn-sm rounded-pill">
@endforelse @endforelse
</div> </div>
{{-- Pagination --}}
@if ($produks->hasPages()) @if ($produks->hasPages())
<div class="d-flex justify-content-center mt-5"> <div class="d-flex justify-content-center mt-5">
{{ $produks->withQueryString()->links() }} {{ $produks->withQueryString()->links() }}
@ -194,7 +181,7 @@ class="btn btn-success btn-sm rounded-pill">
transform: scale(1.05); transform: scale(1.05);
} }
.transition-transform { .overflow-hidden img {
transition: transform 0.5s ease; transition: transform 0.5s ease;
} }
</style> </style>

View File

@ -204,35 +204,6 @@
<div class="logo me-md-2"> <div class="logo me-md-2">
<a href="#" style="color: #81c408;">GriyaPadi.id</a> <a href="#" style="color: #81c408;">GriyaPadi.id</a>
</div> </div>
<div class="theme-toggle d-flex gap-1 align-items-center mt-2">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true" role="img" class="iconify iconify--system-uicons" width="20"
height="20" preserveAspectRatio="xMidYMid meet" viewBox="0 0 21 21">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round">
<path
d="M10.5 14.5c2.219 0 4-1.763 4-3.982a4.003 4.003 0 0 0-4-4.018c-2.219 0-4 1.781-4 4c0 2.219 1.781 4 4 4zM4.136 4.136L5.55 5.55m9.9 9.9l1.414 1.414M1.5 10.5h2m14 0h2M4.135 16.863L5.55 15.45m9.899-9.9l1.414-1.415M10.5 19.5v-2m0-14v-2"
opacity=".3"></path>
<g transform="translate(-210 -1)">
<path d="M220.5 2.5v2m6.5.5l-1.5 1.5"></path>
<circle cx="220.5" cy="11.5" r="4"></circle>
<path d="m214 5l1.5 1.5m5 14v-2m6.5-.5l-1.5-1.5M214 18l1.5-1.5m-4-5h2m14 0h2">
</path>
</g>
</g>
</svg>
<div class="form-check form-switch fs-6">
<input class="form-check-input me-0" type="checkbox" id="toggle-dark">
<label class="form-check-label"></label>
</div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true" role="img" class="iconify iconify--mdi" width="20" height="20"
preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24">
<path fill="currentColor"
d="m17.75 4.09l-2.53 1.94l.91 3.06l-2.63-1.81l-2.63 1.81l.91-3.06l-2.53-1.94L12.44 4l1.06-3l1.06 3l3.19.09m3.5 6.91l-1.64 1.25l.59 1.98l-1.7-1.17l-1.7 1.17l.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95l2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85c-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14c.4-.4.82-.76 1.27-1.08c.75-.53 1.93.36 1.85 1.19c-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82c-2.81 3.14-2.7 7.96.31 10.98c3.02 3.01 7.84 3.12 10.98.31Z">
</path>
</svg>
</div>
<div class="sidebar-toggler x"> <div class="sidebar-toggler x">
<a href="#" class="sidebar-hide d-xl-none d-block"><i class="bi bi-x bi-middle"></i></a> <a href="#" class="sidebar-hide d-xl-none d-block"><i class="bi bi-x bi-middle"></i></a>
</div> </div>
@ -335,7 +306,7 @@ class='sidebar-link border-0 bg-transparent text-danger w-100 text-start'>
</header> </header>
<div class="page-heading"> <div class="page-heading">
<div>@yield('page-title')</div> <div class="fw-bold fs-5">@yield('page-title')</div>
</div> </div>
<div class="page-content"> <div class="page-content">

View File

@ -31,7 +31,6 @@
--muted-text: #6c757d; --muted-text: #6c757d;
} }
body { body {
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
background-color: var(--light-bg); background-color: var(--light-bg);
@ -39,12 +38,7 @@
line-height: 1.6; line-height: 1.6;
} }
h1, h1, h2, h3, h4, h5, h6 {
h2,
h3,
h4,
h5,
h6 {
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
font-weight: 700; font-weight: 700;
color: var(--dark-text); color: var(--dark-text);
@ -52,17 +46,9 @@
} }
/* Utility Colors */ /* Utility Colors */
.text-primary { .text-primary { color: var(--primary-color) !important; }
color: var(--primary-color) !important; .bg-primary { background-color: var(--primary-color) !important; }
} .border-primary { border-color: var(--primary-color) !important; }
.bg-primary {
background-color: var(--primary-color) !important;
}
.border-primary {
border-color: var(--primary-color) !important;
}
/* BUTTON */ /* BUTTON */
.btn { .btn {
@ -136,55 +122,17 @@
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05);
} }
/* CHAT SECTION */ /* DROPDOWN HOVER HIJAU */
.chat-container { .dropdown-item:hover,
height: 80vh; .dropdown-item:focus {
background: #fff; background-color: rgba(129, 196, 8, 0.1) !important;
border-radius: 8px; color: #81c408 !important;
border: 1px solid #e9ecef;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
} }
.message-bubble { .dropdown-item.active,
max-width: 75%; .dropdown-item:active {
padding: 10px 16px; background-color: var(--primary-color) !important;
border-radius: 8px; color: #fff !important;
margin-bottom: 8px;
font-size: 0.9rem;
line-height: 1.5;
}
.message-me {
background-color: var(--primary-color);
color: white;
border-bottom-right-radius: 2px;
margin-left: auto;
}
.message-other {
background-color: #f1f3f5;
color: var(--dark-text);
border-bottom-left-radius: 2px;
margin-right: auto;
}
/* SCROLLBAR */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #bbb;
} }
/* Footer Accent */ /* Footer Accent */
@ -196,24 +144,18 @@
<body> <body>
<div id="spinner" <div id="spinner" class="show w-100 vh-100 bg-white position-fixed translate-middle top-50 start-50 d-flex align-items-center justify-content-center">
class="show w-100 vh-100 bg-white position-fixed translate-middle top-50 start-50 d-flex align-items-center justify-content-center">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;"></div> <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;"></div>
</div> </div>
<div class="container-fluid fixed-top px-0"> <div class="container-fluid fixed-top px-0">
<div class="container-fluid bg-primary d-none d-lg-block py-3"> <div class="container-fluid bg-primary d-none d-lg-block py-3">
<div class="container"> <div class="container">
<div class="d-flex justify-content-between text-white" style="font-size: 0.85rem;"> <div class="d-flex justify-content-start text-white" style="font-size: 0.85rem;">
<div> <div>
<span class="me-3"><i class="fas fa-map-marker-alt me-2"></i> Desa Sukamaju, Indonesia</span> <span class="me-3"><i class="fas fa-map-marker-alt me-2"></i> Desa Mancon, Kecamatan Wilangan, Kabupaten Nganjuk</span>
<span class="me-3"><i class="fas fa-envelope me-2"></i> info@tanidesa.com</span> <span class="me-3"><i class="fas fa-envelope me-2"></i> info@tanidesa.com</span>
</div> </div>
<div>
<a href="#" class="text-white text-decoration-none me-2">Bantuan</a>
<span class="text-white-50">|</span>
<a href="#" class="text-white text-decoration-none ms-2">Ikuti Kami</a>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -222,26 +164,23 @@ class="show w-100 vh-100 bg-white position-fixed translate-middle top-50 start-5
<div class="container"> <div class="container">
<nav class="navbar navbar-light navbar-expand-xl py-3"> <nav class="navbar navbar-light navbar-expand-xl py-3">
<a href="{{ url('/') }}" class="navbar-brand d-flex align-items-center"> <a href="{{ url('/') }}" class="navbar-brand d-flex align-items-center">
<h1 class="text-primary m-0 fw-bold" style="font-size: 1.8rem; letter-spacing: -1px;">GriyaPadi.id <h1 class="text-primary m-0 fw-bold" style="font-size: 1.8rem; letter-spacing: -1px;">GriyaPadi.id</h1>
</h1>
</a> </a>
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" <button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse">
data-bs-target="#navbarCollapse">
<span class="fa fa-bars text-primary"></span> <span class="fa fa-bars text-primary"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarCollapse"> <div class="collapse navbar-collapse" id="navbarCollapse">
<div class="navbar-nav mx-auto"> <div class="navbar-nav mx-auto">
<a href="{{ url('/') }}" <a href="{{ url('/') }}" class="nav-item nav-link mx-2 {{ request()->is('/') ? 'active' : '' }}">Home</a>
class="nav-item nav-link mx-2 {{ request()->is('/') ? 'active' : '' }}">Home</a> <a href="{{ route('shop') }}" class="nav-item nav-link mx-2 {{ request()->is('shop*') ? 'active' : '' }}">Belanja</a>
<a href="{{ route('shop') }}"
class="nav-item nav-link mx-2 {{ request()->is('shop*') ? 'active' : '' }}">Belanja</a>
</div> </div>
<div class="d-flex align-items-center mt-3 mt-xl-0"> <div class="d-flex align-items-center mt-3 mt-xl-0">
<form action="{{ route('shop') }}" method="GET" class="me-3 d-none d-md-flex">
<div class="input-group"> <form action="{{ route('shop') }}" method="GET" class="me-3 d-flex w-100 w-xl-auto mb-3 mb-xl-0">
<div class="input-group w-100">
<input type="search" name="search" class="form-control border-end-0" <input type="search" name="search" class="form-control border-end-0"
placeholder="Cari produk..." value="{{ request('search') }}" placeholder="Cari produk..." value="{{ request('search') }}"
style="border-radius: 6px 0 0 6px;"> style="border-radius: 6px 0 0 6px;">
@ -253,44 +192,40 @@ class="nav-item nav-link mx-2 {{ request()->is('shop*') ? 'active' : '' }}">Bela
</form> </form>
<a href="{{ route('cart') }}" class="position-relative me-3 text-dark"> <a href="{{ route('cart') }}" class="position-relative me-3 text-dark">
<i class="bi bi-bag fs-4"></i> <span <i class="bi bi-bag fs-4"></i>
class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" style="font-size: 0.6rem;">
style="font-size: 0.6rem;">
{{ count((array) session('cart')) }} {{-- PERBAIKAN LOGIKA HITUNG CART --}}
@if(Auth::guard('pembeli')->check())
{{ \App\Models\Cart::where('pembeli_id', Auth::guard('pembeli')->id())->count() }}
@else
0
@endif
</span> </span>
</a> </a>
@if (Auth::guard('pembeli')->check()) @if (Auth::guard('pembeli')->check())
<div class="nav-item dropdown ms-2"> <div class="nav-item dropdown ms-2">
<a href="#" <a href="#" class="nav-link dropdown-toggle text-dark fw-bold d-flex align-items-center" data-bs-toggle="dropdown">
class="nav-link dropdown-toggle text-dark fw-bold d-flex align-items-center" <div class="bg-light rounded-circle d-flex align-items-center justify-content-center me-2" style="width: 35px; height: 35px;">
data-bs-toggle="dropdown">
<div class="bg-light rounded-circle d-flex align-items-center justify-content-center me-2"
style="width: 35px; height: 35px;">
<i class="fas fa-user text-primary"></i> <i class="fas fa-user text-primary"></i>
</div> </div>
<span <span class="d-none d-xl-inline small">{{ Auth::guard('pembeli')->user()->nama_lengkap }}</span>
class="d-none d-xl-inline small">{{ Auth::guard('pembeli')->user()->nama_lengkap }}</span>
</a> </a>
<div class="dropdown-menu dropdown-menu-end border-0 shadow-sm m-0 rounded-3"> <div class="dropdown-menu dropdown-menu-end border-0 shadow-sm m-0 rounded-3">
<a href="{{ route('pembeli.profile') }}" class="dropdown-item py-2"><i <a href="{{ route('pembeli.profile') }}" class="dropdown-item py-2"><i class="bi bi-person me-2"></i> Profil</a>
class="bi bi-person me-2"></i> Profil</a> <a href="{{ route('pembeli.pesan.index') }}" class="dropdown-item py-2"><i class="bi bi-chat-dots me-2"></i> Pesan</a>
<a href="{{ route('pembeli.pesan.index') }}" class="dropdown-item py-2"><i <a href="{{ route('pesanan.saya') }}" class="dropdown-item py-2"><i class="bi bi-bag-check me-2"></i> Riwayat Pesanan</a>
class="bi bi-chat-dots me-2"></i> Pesan</a>
<a href="{{ route('pesanan.saya') }}" class="dropdown-item py-2"><i
class="bi bi-bag-check me-2"></i> Riwayat Pesanan</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<form action="{{ route('logout') }}" method="POST"> <form action="{{ route('logout') }}" method="POST">
@csrf @csrf
<button type="submit" class="dropdown-item py-2 text-danger"><i <button type="submit" class="dropdown-item py-2 text-danger"><i class="bi bi-box-arrow-right me-2"></i> Logout</button>
class="bi bi-box-arrow-right me-2"></i> Logout</button>
</form> </form>
</div> </div>
</div> </div>
@else @else
<a href="{{ route('login') }}" class="btn btn-primary px-4 ms-2"> <a href="{{ route('login') }}" class="btn btn-primary px-4 ms-2">Login</a>
Login
</a>
@endif @endif
</div> </div>
</div> </div>
@ -302,12 +237,10 @@ class="bi bi-box-arrow-right me-2"></i> Logout</button>
<div style="margin-top: 170px;"> <div style="margin-top: 170px;">
@if (session('success')) @if (session('success'))
<div class="container mt-4"> <div class="container mt-4">
<div class="alert alert-success border-0 shadow-sm rounded-3 d-flex align-items-center" <div class="alert alert-success border-0 shadow-sm rounded-3 d-flex align-items-center" role="alert">
role="alert">
<i class="bi bi-check-circle-fill fs-4 me-3"></i> <i class="bi bi-check-circle-fill fs-4 me-3"></i>
<div>{{ session('success') }}</div> <div>{{ session('success') }}</div>
<button type="button" class="btn-close ms-auto" data-bs-dismiss="alert" <button type="button" class="btn-close ms-auto" data-bs-dismiss="alert" aria-label="Close"></button>
aria-label="Close"></button>
</div> </div>
</div> </div>
@endif @endif
@ -320,37 +253,27 @@ class="bi bi-box-arrow-right me-2"></i> Logout</button>
<div class="row g-5"> <div class="row g-5">
<div class="col-lg-3 col-md-6"> <div class="col-lg-3 col-md-6">
<h3 class="text-white mb-4">GriyaPadi.id</h3> <h3 class="text-white mb-4">GriyaPadi.id</h3>
<p class="mb-4 small">Menghubungkan petani lokal langsung dengan pembeli untuk harga yang adil dan <p class="mb-4 small">Menghubungkan petani lokal langsung dengan pembeli untuk harga yang adil dan produk berkualitas tinggi.</p>
produk berkualitas tinggi.</p>
<div class="d-flex pt-2"> <div class="d-flex pt-2">
<a class="btn btn-outline-light btn-sm rounded-circle me-2" href=""><i <a class="btn btn-outline-light btn-sm rounded-circle me-2" href=""><i class="fab fa-twitter"></i></a>
class="fab fa-twitter"></i></a> <a class="btn btn-outline-light btn-sm rounded-circle me-2" href=""><i class="fab fa-facebook-f"></i></a>
<a class="btn btn-outline-light btn-sm rounded-circle me-2" href=""><i <a class="btn btn-outline-light btn-sm rounded-circle" href=""><i class="fab fa-youtube"></i></a>
class="fab fa-facebook-f"></i></a>
<a class="btn btn-outline-light btn-sm rounded-circle" href=""><i
class="fab fa-youtube"></i></a>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-lg-3 col-md-6">
<h5 class="text-white mb-4">Tautan Cepat</h5> <h5 class="text-white mb-4">Tautan Cepat</h5>
<div class="d-flex flex-column justify-content-start"> <div class="d-flex flex-column justify-content-start">
<a class="text-white-50 mb-2 text-decoration-none" href="{{ route('shop') }}"><i <a class="text-white-50 mb-2 text-decoration-none" href="{{ route('shop') }}"><i class="bi bi-chevron-right me-2 small"></i>Belanja</a>
class="bi bi-chevron-right me-2 small"></i>Belanja</a> <a class="text-white-50 mb-2 text-decoration-none" href="#"><i class="bi bi-chevron-right me-2 small"></i>Tentang Kami</a>
<a class="text-white-50 mb-2 text-decoration-none" href="#"><i <a class="text-white-50 text-decoration-none" href="#"><i class="bi bi-chevron-right me-2 small"></i>Hubungi Kami</a>
class="bi bi-chevron-right me-2 small"></i>Tentang Kami</a>
<a class="text-white-50 text-decoration-none" href="#"><i
class="bi bi-chevron-right me-2 small"></i>Hubungi Kami</a>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-lg-3 col-md-6">
<h5 class="text-white mb-4">Akun Saya</h5> <h5 class="text-white mb-4">Akun Saya</h5>
<div class="d-flex flex-column justify-content-start"> <div class="d-flex flex-column justify-content-start">
<a class="text-white-50 mb-2 text-decoration-none" href="{{ route('pembeli.profile') }}"><i <a class="text-white-50 mb-2 text-decoration-none" href="{{ route('pembeli.profile') }}"><i class="bi bi-chevron-right me-2 small"></i>Profil</a>
class="bi bi-chevron-right me-2 small"></i>Profil</a> <a class="text-white-50 mb-2 text-decoration-none" href="{{ route('cart') }}"><i class="bi bi-chevron-right me-2 small"></i>Keranjang</a>
<a class="text-white-50 mb-2 text-decoration-none" href="{{ route('cart') }}"><i <a class="text-white-50 text-decoration-none" href="{{ route('pesanan.saya') }}"><i class="bi bi-chevron-right me-2 small"></i>Riwayat Pesanan</a>
class="bi bi-chevron-right me-2 small"></i>Keranjang</a>
<a class="text-white-50 text-decoration-none" href="{{ route('pesanan.saya') }}"><i
class="bi bi-chevron-right me-2 small"></i>Riwayat Pesanan</a>
</div> </div>
</div> </div>
<div class="col-lg-3 col-md-6"> <div class="col-lg-3 col-md-6">
@ -363,14 +286,12 @@ class="bi bi-chevron-right me-2 small"></i>Riwayat Pesanan</a>
</div> </div>
<div class="container-fluid copyright bg-dark py-4 border-top border-secondary"> <div class="container-fluid copyright bg-dark py-4 border-top border-secondary">
<div class="container text-center"> <div class="container text-center">
<span class="text-white-50 small">&copy; <a href="#" class="text-white">GriyaPadi.id</a>, All Right <span class="text-white-50 small">&copy; <a href="#" class="text-white">GriyaPadi.id</a>, All Right Reserved.</span>
Reserved.</span>
</div> </div>
</div> </div>
</div> </div>
<a href="#" class="btn btn-primary btn-lg-square rounded-circle back-to-top shadow"><i <a href="#" class="btn btn-primary btn-lg-square rounded-circle back-to-top shadow"><i class="bi bi-arrow-up"></i></a>
class="bi bi-arrow-up"></i></a>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"></script>

View File

@ -24,7 +24,7 @@
</div> </div>
</div> </div>
{{-- Card 2: Pesanan Baru --}} {{-- Card Pemesanan --}}
<div class="col-6 col-lg-4 col-md-6"> <div class="col-6 col-lg-4 col-md-6">
<div class="card"> <div class="card">
<div class="card-body px-3 py-4-5"> <div class="card-body px-3 py-4-5">
@ -35,15 +35,15 @@
</div> </div>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<h6 class="text-muted font-semibold">Pesanan Baru</h6> <h6 class="text-muted font-semibold">Pemesanan</h6>
<h6 class="font-extrabold mb-0">{{ $pesananBaru }}</h6> <h6 class="font-extrabold mb-0">{{ $totalPemesanan }}</h6>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{{-- Card 3: Total Pendapatan --}} {{-- Card Total Pendapatan --}}
<div class="col-6 col-lg-4 col-md-6"> <div class="col-6 col-lg-4 col-md-6">
<div class="card"> <div class="card">
<div class="card-body px-3 py-4-5"> <div class="card-body px-3 py-4-5">

View File

@ -4,7 +4,10 @@
@section('page-title') @section('page-title')
<div class="d-flex align-items-center justify-content-between"> <div class="d-flex align-items-center justify-content-between">
<div> <div>
<h4 class="mb-0">Detail Pesanan</h4> <div class="d-flex align-items-center gap-1 mb-1">
<a href="{{ route('petani.pesanan.index', $pesanan->id) }}">Daftar Pesanan </a>
<p class="mb-0">/ Detail Pesanan</p>
</div>
<p class="text-muted font-bold mb-0">Invoice: #{{ $pesanan->kode_invoice }}</p> <p class="text-muted font-bold mb-0">Invoice: #{{ $pesanan->kode_invoice }}</p>
</div> </div>
<a href="{{ route('petani.pesanan.index') }}" class="btn btn-light"> <a href="{{ route('petani.pesanan.index') }}" class="btn btn-light">
@ -41,7 +44,7 @@
<img src="{{ $detail->produk->foto_produk ? asset('storage/' . $detail->produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=200&auto=format&fit=crop' }}" <img src="{{ $detail->produk->foto_produk ? asset('storage/' . $detail->produk->foto_produk) : 'https://images.unsplash.com/photo-1586201375761-83865001e31c?q=80&w=200&auto=format&fit=crop' }}"
class="rounded me-3" width="50" height="50" style="object-fit: cover;"> class="rounded me-3" width="50" height="50" style="object-fit: cover;">
<div> <div>
<h6 class="mb-1">{{ $detail->produk->nama_produk }}</h6> <p class="mb-1 fw-bold">{{ $detail->produk->nama_produk }}</p>
<span <span
class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'Umum' }}</span> class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'Umum' }}</span>
</div> </div>
@ -67,7 +70,7 @@ class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'U
return $detail->produk->petani_id == Auth::guard('petani')->id(); return $detail->produk->petani_id == Auth::guard('petani')->id();
})->sum('subtotal'); })->sum('subtotal');
@endphp @endphp
<h4 class="mb-0 text-primary fw-bold">Rp {{ number_format($totalPetani, 0, ',', '.') }}</h4> <h4 class="mb-0 fw-bold">Rp {{ number_format($totalPetani, 0, ',', '.') }}</h4>
</div> </div>
</div> </div>
</div> </div>
@ -79,7 +82,7 @@ class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'U
@if($pesanan->status == 'menunggu_konfirmasi' || $pesanan->status == 'menunggu konfirmasi') @if($pesanan->status == 'menunggu_konfirmasi' || $pesanan->status == 'menunggu konfirmasi')
<div class="card mb-3"> <div class="card mb-3">
<div class="card-body"> <div class="card-body">
<div class="alert alert-warning mb-3"> <div class="mb-3">
<h6 class="alert-heading mb-2">Perlu Konfirmasi</h6> <h6 class="alert-heading mb-2">Perlu Konfirmasi</h6>
<p class="mb-0 small">Pastikan stok tersedia sebelum menerima pesanan ini.</p> <p class="mb-0 small">Pastikan stok tersedia sebelum menerima pesanan ini.</p>
</div> </div>
@ -103,9 +106,8 @@ class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'U
</div> </div>
@elseif($pesanan->status == 'diproses') @elseif($pesanan->status == 'diproses')
<div class="card mb-3"> <div class="card mb-3">
<div class="card-body text-center"> <div class="card-body">
<div class="alert alert-info"> <div class="mb-3">
<i class="bi bi-box-seam fs-2 d-block mb-2"></i>
<h6 class="alert-heading">Sedang Diproses</h6> <h6 class="alert-heading">Sedang Diproses</h6>
<p class="mb-0 small">Klik tombol di bawah jika barang sudah diserahkan ke kurir.</p> <p class="mb-0 small">Klik tombol di bawah jika barang sudah diserahkan ke kurir.</p>
</div> </div>
@ -113,7 +115,7 @@ class="badge bg-primary-green">{{ $detail->produk->kategori->nama_kategori ?? 'U
@csrf @method('PATCH') @csrf @method('PATCH')
<input type="hidden" name="status" value="dikirim"> <input type="hidden" name="status" value="dikirim">
<button class="btn btn-info w-100"> <button class="btn btn-info w-100">
<i class="bi bi-truck"></i> Update Jadi Dikirim <i class="bi bi-truck"></i> Update Pengiriman
</button> </button>
</form> </form>
</div> </div>

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
@if(session('success')) @if(session('success'))
<div class="alert alert-success">{{ session('success') }}</div> <div class="alert alert-success border-0 shadow-sm rounded-3 d-flex align-items-center">{{ session('success') }}</div>
@endif @endif
<div class="table-responsive"> <div class="table-responsive">
@ -59,7 +59,7 @@
<td> <td>
<a href="{{ route('petani.pesanan.detail', $pesanan->id) }}" <a href="{{ route('petani.pesanan.detail', $pesanan->id) }}"
class="btn btn-sm btn-outline-primary rounded-pill px-3"> class="btn btn-sm btn-outline-primary rounded-pill px-3">
Lihat Detail <i class="bi bi-arrow-right ms-1"></i> Detail
</a> </a>
</td> </td>
</tr> </tr>

View File

@ -137,7 +137,7 @@ class="form-control form-control-sm" accept="image/*" multiple>
<div class="border-top pt-3 mt-4 text-end"> <div class="border-top pt-3 mt-4 text-end">
<a href="{{ route('petani.produk.index') }}" class="btn btn-secondary me-2">Batal</a> <a href="{{ route('petani.produk.index') }}" class="btn btn-secondary me-2">Batal</a>
<button type="submit" class="btn btn-success px-4">Update Produk</button> <button type="submit" class="btn btn-primary px-4">Update Produk</button>
</div> </div>
</form> </form>

View File

@ -4,85 +4,87 @@
@section('page-title', 'Daftar Produk Saya') @section('page-title', 'Daftar Produk Saya')
@section('content') @section('content')
<div class="card"> <div class="card">
<div class="card-header d-flex justify-content-between align-items-center"> <div class="card-header d-flex justify-content-between align-items-center">
<h4 class="card-title">List Produk Pertanian</h4> <h4 class="card-title">List Produk Pertanian</h4>
<a href="{{ route('petani.produk.create') }}" class="btn btn-primary"> <a href="{{ route('petani.produk.create') }}" class="btn btn-primary">
<i class="bi bi-plus-lg"></i> Tambah Produk <i class="bi bi-plus-lg"></i> Tambah Produk
</a> </a>
</div> </div>
<div class="card-body"> <div class="card-body">
@if(session('success')) @if(session('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert"> <div class="alert alert-light-success alert-dismissible fade show" role="alert">
<i class="bi bi-check-circle"></i> {{ session('success') }} <i class="bi bi-check-circle"></i> {{ session('success') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
<div class="table-responsive">
<table class="table table-hover table-lg">
<thead>
<tr>
<th>Foto</th>
<th>Nama Produk</th>
<th>Harga (Rp)</th>
<th>Stok</th>
<th class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($produks as $produk)
<tr>
<td class="col-1">
@if($produk->foto_produk)
<img src="{{ asset('storage/' . $produk->foto_produk) }}" alt="{{ $produk->nama_produk }}"
class="rounded" style="width: 80px; height: 80px; object-fit: cover;">
@else
<span class="badge bg-secondary">No Image</span>
@endif
</td>
<td>
<p class="font-bold mb-0">{{ $produk->nama_produk }}</p>
<small class="text-muted">{{ Str::limit($produk->deskripsi, 50) }}</small>
</td>
<td>Rp {{ number_format($produk->harga, 0, ',', '.') }}</td>
<td>
@if($produk->stok > 0)
<span class="badge bg-success">{{ $produk->stok }} kg</span>
@else
<span class="badge bg-danger">Habis</span>
@endif
</td>
<td class="text-center">
{{-- Tombol Edit --}}
<a href="{{ route('petani.produk.edit', $produk->id) }}"
class="btn btn-sm btn-warning me-1">
<i class="bi bi-pencil-square"></i>
</a>
{{-- Form Hapus --}}
<form action="{{ route('petani.produk.destroy', $produk->id) }}" method="POST"
class="d-inline" onsubmit="return confirm('Yakin ingin menghapus produk ini?')">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-danger">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center py-5">
<img src="{{ asset('template/admin/static/images/samples/error-404.svg') }}" width="150"
class="mb-3">
<p class="text-muted">Belum ada produk yang dijual.</p>
<a href="{{ route('petani.produk.create') }}" class="btn btn-primary btn-sm">Tambah Produk
Sekarang</a>
</td>
</tr>
@endforelse
</tbody>
</table>
</div> </div>
@endif
<div class="table-responsive">
<table class="table table-hover table-lg">
<thead>
<tr>
<th>Foto</th>
<th>Nama Produk</th>
<th>Harga (Rp)</th>
<th>Stok</th>
<th class="text-center">Aksi</th>
</tr>
</thead>
<tbody>
@forelse($produks as $produk)
<tr>
<td class="col-1">
@if($produk->foto_produk)
<img src="{{ asset('storage/'.$produk->foto_produk) }}"
alt="{{ $produk->nama_produk }}"
class="rounded"
style="width: 80px; height: 80px; object-fit: cover;">
@else
<span class="badge bg-secondary">No Image</span>
@endif
</td>
<td>
<p class="font-bold mb-0">{{ $produk->nama_produk }}</p>
<small class="text-muted">{{ Str::limit($produk->deskripsi, 50) }}</small>
</td>
<td>Rp {{ number_format($produk->harga, 0, ',', '.') }}</td>
<td>
@if($produk->stok > 0)
<span class="badge bg-success">{{ $produk->stok }} kg</span>
@else
<span class="badge bg-danger">Habis</span>
@endif
</td>
<td class="text-center">
{{-- Tombol Edit --}}
<a href="{{ route('petani.produk.edit', $produk->id) }}" class="btn btn-sm btn-warning me-1">
<i class="bi bi-pencil-square"></i>
</a>
{{-- Form Hapus --}}
<form action="{{ route('petani.produk.destroy', $produk->id) }}" method="POST" class="d-inline" onsubmit="return confirm('Yakin ingin menghapus produk ini?')">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-danger">
<i class="bi bi-trash"></i>
</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="5" class="text-center py-5">
<img src="{{ asset('template/admin/static/images/samples/error-404.svg') }}" width="150" class="mb-3">
<p class="text-muted">Belum ada produk yang dijual.</p>
<a href="{{ route('petani.produk.create') }}" class="btn btn-primary btn-sm">Tambah Produk Sekarang</a>
</td>
</tr>
@endforelse
</tbody>
</table>
</div> </div>
</div> </div>
</div>
@endsection @endsection

View File

@ -3,7 +3,7 @@
use App\Http\Controllers\Admin\KategoriController; use App\Http\Controllers\Admin\KategoriController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController; use App\Http\Controllers\AuthController;
use App\Http\Controllers\AdminController; use App\Http\Controllers\Admin\AdminController;
use App\Http\Controllers\CartController; use App\Http\Controllers\CartController;
use App\Http\Controllers\ForgotPasswordController; use App\Http\Controllers\ForgotPasswordController;
use App\Http\Controllers\LandingController; use App\Http\Controllers\LandingController;