refactor: transaksi controller, cart dan filter wilayah lengkap
This commit is contained in:
parent
69a3234d0b
commit
f01c00fa87
|
|
@ -22,3 +22,6 @@
|
||||||
Homestead.json
|
Homestead.json
|
||||||
Homestead.yaml
|
Homestead.yaml
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
/storage/framework/views/*.php
|
||||||
|
/storage/framework/cache/data/*
|
||||||
|
/storage/framework/sessions/*
|
||||||
11
README.md
11
README.md
|
|
@ -141,14 +141,21 @@ ### Step 6: Database Migration
|
||||||
php artisan migrate --seed
|
php artisan migrate --seed
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 7: Konfigurasi Storage Link
|
### Step 7: Import Data Wilayah Indonesia (Wajib)
|
||||||
|
Jalankan perintah ini untuk mengisi data wilayah resmi Indonesia ke dalam database.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
php artisan laravolt:indonesia:seed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 8: Konfigurasi Storage Link
|
||||||
Jalankan perintah untuk konfigurasi storage link untuk menyimpan gambar
|
Jalankan perintah untuk konfigurasi storage link untuk menyimpan gambar
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php artisan storage:link
|
php artisan storage:link
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 8: Start Application
|
### Step 9: Start Application
|
||||||
**Terminal (Laravel Server):**
|
**Terminal (Laravel Server):**
|
||||||
```bash
|
```bash
|
||||||
php artisan serve
|
php artisan serve
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,16 @@ class CartController extends Controller
|
||||||
// Menampilkan Halaman Keranjang
|
// Menampilkan Halaman Keranjang
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// Cek Login Pembeli
|
|
||||||
if (!Auth::guard('pembeli')->check()) {
|
if (!Auth::guard('pembeli')->check()) {
|
||||||
return redirect()->route('login')->with('error', 'Silakan login terlebih dahulu untuk melihat keranjang.');
|
return redirect()->route('login')->with('error', 'Silakan login terlebih dahulu untuk melihat keranjang.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$pembeli_id = Auth::guard('pembeli')->id();
|
$pembeli_id = Auth::guard('pembeli')->id();
|
||||||
|
|
||||||
// Ambil data keranjang dari Database
|
$cart = Cart::with('produk')
|
||||||
$cart = Cart::with('produk')->where('pembeli_id', $pembeli_id)->get();
|
->where('pembeli_id', $pembeli_id)
|
||||||
|
->latest()
|
||||||
|
->get();
|
||||||
|
|
||||||
return view('landing.cart', compact('cart'));
|
return view('landing.cart', compact('cart'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,13 @@ public function index(Request $request)
|
||||||
return view('landing.partials.product_list', compact('produks'))->render();
|
return view('landing.partials.product_list', compact('produks'))->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
$produkTerlaris = Produk::withSum(['detailTransaksis as total_terjual' => function ($query) {
|
$produkTerlaris = Produk::withSum([
|
||||||
|
'detailTransaksis as total_terjual' => function ($query) {
|
||||||
$query->whereHas('transaksi', function ($q) {
|
$query->whereHas('transaksi', function ($q) {
|
||||||
$q->where('status', '!=', 'batal');
|
$q->where('status', '!=', 'batal');
|
||||||
});
|
});
|
||||||
}], 'jumlah')
|
}
|
||||||
|
], 'jumlah')
|
||||||
->orderByDesc('total_terjual')
|
->orderByDesc('total_terjual')
|
||||||
->take(4)
|
->take(4)
|
||||||
->get();
|
->get();
|
||||||
|
|
@ -41,6 +43,21 @@ public function shop(Request $request)
|
||||||
{
|
{
|
||||||
$query = Produk::where('stok', '>', 0);
|
$query = Produk::where('stok', '>', 0);
|
||||||
|
|
||||||
|
// --- FILTER LOKASI ---
|
||||||
|
if ($request->filled('provinsi')) {
|
||||||
|
$query->where('provinsi_code', $request->provinsi);
|
||||||
|
}
|
||||||
|
if ($request->filled('kota')) {
|
||||||
|
$query->where('kota_code', $request->kota);
|
||||||
|
}
|
||||||
|
if ($request->filled('kecamatan')) {
|
||||||
|
$query->where('kecamatan_code', $request->kecamatan);
|
||||||
|
}
|
||||||
|
if ($request->filled('desa')) {
|
||||||
|
$query->where('desa_code', $request->desa);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter Search
|
||||||
if ($request->has('search') && $request->search != '') {
|
if ($request->has('search') && $request->search != '') {
|
||||||
$query->where('nama_produk', 'like', '%' . $request->search . '%');
|
$query->where('nama_produk', 'like', '%' . $request->search . '%');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,13 @@
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Produk;
|
use App\Models\Produk;
|
||||||
use App\Models\ProdukImage;
|
use App\Models\ProdukImage;
|
||||||
use App\Models\Kategori; // PENTING: Import Model Kategori
|
use App\Models\Kategori;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Laravolt\Indonesia\Models\City;
|
||||||
|
use Laravolt\Indonesia\Models\District;
|
||||||
|
use Laravolt\Indonesia\Models\Province;
|
||||||
|
use Laravolt\Indonesia\Models\Village;
|
||||||
|
|
||||||
class ProdukController extends Controller
|
class ProdukController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -25,8 +29,9 @@ public function index()
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
$kategoris = Kategori::all();
|
$kategoris = Kategori::all();
|
||||||
|
$provinsis = Province::all();
|
||||||
|
|
||||||
return view('petani.produk.create', compact('kategoris'));
|
return view('petani.produk.create', compact('kategoris', 'provinsis'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
|
|
@ -37,6 +42,10 @@ public function store(Request $request)
|
||||||
'harga' => 'required|numeric|min:0',
|
'harga' => 'required|numeric|min:0',
|
||||||
'stok' => 'required|integer|min:0',
|
'stok' => 'required|integer|min:0',
|
||||||
'deskripsi' => 'required|string',
|
'deskripsi' => 'required|string',
|
||||||
|
'provinsi_code' => 'required',
|
||||||
|
'kota_code' => 'required',
|
||||||
|
'kecamatan_code' => 'required',
|
||||||
|
'desa_code' => 'required',
|
||||||
'foto_produk' => 'required|image|mimes:jpeg,png,jpg|max:2048',
|
'foto_produk' => 'required|image|mimes:jpeg,png,jpg|max:2048',
|
||||||
'foto_tambahan.*' => 'nullable|image|mimes:jpeg,png,jpg|max:2048'
|
'foto_tambahan.*' => 'nullable|image|mimes:jpeg,png,jpg|max:2048'
|
||||||
]);
|
]);
|
||||||
|
|
@ -53,6 +62,10 @@ public function store(Request $request)
|
||||||
'kategori_id' => $request->kategori_id,
|
'kategori_id' => $request->kategori_id,
|
||||||
'nama_produk' => $request->nama_produk,
|
'nama_produk' => $request->nama_produk,
|
||||||
'harga' => $request->harga,
|
'harga' => $request->harga,
|
||||||
|
'provinsi_code' => $request->provinsi_code,
|
||||||
|
'kota_code' => $request->kota_code,
|
||||||
|
'kecamatan_code' => $request->kecamatan_code,
|
||||||
|
'desa_code' => $request->desa_code,
|
||||||
'stok' => $request->stok,
|
'stok' => $request->stok,
|
||||||
'deskripsi' => $request->deskripsi,
|
'deskripsi' => $request->deskripsi,
|
||||||
'foto_produk' => $fotoPath,
|
'foto_produk' => $fotoPath,
|
||||||
|
|
@ -77,7 +90,12 @@ public function edit($id)
|
||||||
$produk = Produk::with('images')->where('id', $id)->where('petani_id', Auth::guard('petani')->id())->firstOrFail();
|
$produk = Produk::with('images')->where('id', $id)->where('petani_id', Auth::guard('petani')->id())->firstOrFail();
|
||||||
$kategoris = Kategori::all();
|
$kategoris = Kategori::all();
|
||||||
|
|
||||||
return view('petani.produk.edit', compact('produk', 'kategoris'));
|
$provinsis = Province::all();
|
||||||
|
$kotas = City::where('province_code', $produk->provinsi_code)->get();
|
||||||
|
$kecamatans = District::where('city_code', $produk->kota_code)->get();
|
||||||
|
$desas = Village::where('district_code', $produk->kecamatan_code)->get();
|
||||||
|
|
||||||
|
return view('petani.produk.edit', compact('produk', 'kategoris', 'provinsis', 'kotas', 'kecamatans', 'desas'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id)
|
||||||
|
|
@ -92,6 +110,10 @@ public function update(Request $request, $id)
|
||||||
'nama_produk' => 'required|string|max:255',
|
'nama_produk' => 'required|string|max:255',
|
||||||
'kategori_id' => 'required|exists:kategoris,id',
|
'kategori_id' => 'required|exists:kategoris,id',
|
||||||
'harga' => 'required|numeric|min:0',
|
'harga' => 'required|numeric|min:0',
|
||||||
|
'provinsi_code' => 'required',
|
||||||
|
'kota_code' => 'required',
|
||||||
|
'kecamatan_code' => 'required',
|
||||||
|
'desa_code' => 'required',
|
||||||
'stok' => 'required|integer|min:0',
|
'stok' => 'required|integer|min:0',
|
||||||
'deskripsi' => 'required|string',
|
'deskripsi' => 'required|string',
|
||||||
'foto_produk' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
|
'foto_produk' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
|
||||||
|
|
@ -114,6 +136,10 @@ public function update(Request $request, $id)
|
||||||
'nama_produk' => $request->nama_produk,
|
'nama_produk' => $request->nama_produk,
|
||||||
'kategori_id' => $request->kategori_id,
|
'kategori_id' => $request->kategori_id,
|
||||||
'harga' => $request->harga,
|
'harga' => $request->harga,
|
||||||
|
'provinsi_code' => $request->provinsi_code,
|
||||||
|
'kota_code' => $request->kota_code,
|
||||||
|
'kecamatan_code' => $request->kecamatan_code,
|
||||||
|
'desa_code' => $request->desa_code,
|
||||||
'stok' => $request->stok,
|
'stok' => $request->stok,
|
||||||
'deskripsi' => $request->deskripsi,
|
'deskripsi' => $request->deskripsi,
|
||||||
'foto_produk' => $produk->foto_produk
|
'foto_produk' => $produk->foto_produk
|
||||||
|
|
@ -122,7 +148,8 @@ public function update(Request $request, $id)
|
||||||
// Tambah Foto Galeri
|
// Tambah Foto Galeri
|
||||||
if ($request->hasFile('foto_tambahan')) {
|
if ($request->hasFile('foto_tambahan')) {
|
||||||
foreach ($request->file('foto_tambahan') as $file) {
|
foreach ($request->file('foto_tambahan') as $file) {
|
||||||
if ($produk->images()->count() >= 3) break;
|
if ($produk->images()->count() >= 3)
|
||||||
|
break;
|
||||||
|
|
||||||
$path = $file->store('produk/gallery', 'public');
|
$path = $file->store('produk/gallery', 'public');
|
||||||
ProdukImage::create([
|
ProdukImage::create([
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
use App\Models\Produk;
|
use App\Models\Produk;
|
||||||
use App\Models\Transaksi;
|
use App\Models\Transaksi;
|
||||||
use App\Models\DetailTransaksi;
|
use App\Models\DetailTransaksi;
|
||||||
|
use App\Models\Cart;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
|
@ -13,10 +14,16 @@ class TransaksiController extends Controller
|
||||||
{
|
{
|
||||||
// --- FITUR PEMBELI ---
|
// --- FITUR PEMBELI ---
|
||||||
|
|
||||||
// Tampilkan Halaman Checkout
|
/**
|
||||||
|
* Tampilkan Halaman Checkout
|
||||||
|
* Mendukung Beli Langsung dan Checkout dari Keranjang (Database)
|
||||||
|
*/
|
||||||
public function checkoutPage(Request $request)
|
public function checkoutPage(Request $request)
|
||||||
{
|
{
|
||||||
// Beli Langsung (Buy Now)
|
// Mendefinisikan ID Pembeli agar tidak error 'Undefined Variable'
|
||||||
|
$pembeli_id = Auth::guard('pembeli')->id();
|
||||||
|
|
||||||
|
// 1. LOGIKA BELI LANGSUNG (Buy Now)
|
||||||
if ($request->has('produk_id')) {
|
if ($request->has('produk_id')) {
|
||||||
$produk = Produk::with('petani')->findOrFail($request->produk_id);
|
$produk = Produk::with('petani')->findOrFail($request->produk_id);
|
||||||
$items = collect([
|
$items = collect([
|
||||||
|
|
@ -34,32 +41,48 @@ public function checkoutPage(Request $request)
|
||||||
return view('landing.checkout', compact('items', 'total_belanja'));
|
return view('landing.checkout', compact('items', 'total_belanja'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checkout dari Keranjang
|
// 2. LOGIKA CHECKOUT DARI KERANJANG (Database)
|
||||||
$cart = session()->get('cart');
|
$cartIds = $request->query('cart_ids');
|
||||||
if ($cart && count($cart) > 0) {
|
|
||||||
$items = collect();
|
if (!$cartIds) {
|
||||||
foreach ($cart as $id => $details) {
|
return redirect()->route('cart')->with('error', 'Pilih minimal satu produk di keranjang untuk dicheckout.');
|
||||||
$produk = Produk::find($id);
|
|
||||||
if ($produk) {
|
|
||||||
$items->push((object) [
|
|
||||||
'id' => $id,
|
|
||||||
'produk' => $produk,
|
|
||||||
'nama_produk' => $details['name'],
|
|
||||||
'harga' => $details['price'],
|
|
||||||
'jumlah' => $details['quantity'],
|
|
||||||
'subtotal' => $details['price'] * $details['quantity'],
|
|
||||||
'foto' => $details['photo']
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$selectedIds = explode(',', $cartIds);
|
||||||
|
|
||||||
|
// Ambil data dari Tabel Cart yang ID-nya dicentang oleh user
|
||||||
|
$cartItems = Cart::with('produk.petani')
|
||||||
|
->where('pembeli_id', $pembeli_id)
|
||||||
|
->whereIn('id', $selectedIds)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
if ($cartItems->isEmpty()) {
|
||||||
|
return redirect()->route('cart')->with('error', 'Barang di keranjang tidak ditemukan atau sudah dihapus.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transformasi data agar sesuai dengan format yang dibaca di View Checkout
|
||||||
|
$items = $cartItems->map(function ($item) {
|
||||||
|
return (object) [
|
||||||
|
'cart_id' => $item->id,
|
||||||
|
'id' => $item->produk->id,
|
||||||
|
'produk' => $item->produk,
|
||||||
|
'nama_produk' => $item->produk->nama_produk,
|
||||||
|
'harga' => $item->produk->harga,
|
||||||
|
'jumlah' => $item->quantity,
|
||||||
|
'subtotal' => $item->produk->harga * $item->quantity,
|
||||||
|
'foto' => $item->produk->foto_produk
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
$total_belanja = $items->sum('subtotal');
|
$total_belanja = $items->sum('subtotal');
|
||||||
|
|
||||||
return view('landing.checkout', compact('items', 'total_belanja'));
|
return view('landing.checkout', compact('items', 'total_belanja'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('shop')->with('error', 'Keranjang Anda kosong, silakan belanja dulu.');
|
/**
|
||||||
}
|
* Proses Pembuatan Transaksi
|
||||||
|
* Mengelompokkan pesanan berdasarkan Petani dan membersihkan keranjang
|
||||||
// fungsi prosesCheckout
|
*/
|
||||||
public function prosesCheckout(Request $request)
|
public function prosesCheckout(Request $request)
|
||||||
{
|
{
|
||||||
$request->validate([
|
$request->validate([
|
||||||
|
|
@ -72,7 +95,7 @@ public function prosesCheckout(Request $request)
|
||||||
DB::transaction(function () use ($request, $pembeli_id) {
|
DB::transaction(function () use ($request, $pembeli_id) {
|
||||||
|
|
||||||
if ($request->has('produk_id')) {
|
if ($request->has('produk_id')) {
|
||||||
// --- LOGIKA BELI LANGSUNG (Single Item) ---
|
// --- LOGIKA BELI LANGSUNG ---
|
||||||
$produk = Produk::findOrFail($request->produk_id);
|
$produk = Produk::findOrFail($request->produk_id);
|
||||||
$total_harga = $produk->harga * $request->jumlah;
|
$total_harga = $produk->harga * $request->jumlah;
|
||||||
|
|
||||||
|
|
@ -97,65 +120,64 @@ public function prosesCheckout(Request $request)
|
||||||
$produk->decrement('stok', $request->jumlah);
|
$produk->decrement('stok', $request->jumlah);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// --- LOGIKA KERANJANG (Cart) ---
|
// --- LOGIKA KERANJANG (DATABASE) ---
|
||||||
$cart = session()->get('cart');
|
if (!$request->cart_ids) {
|
||||||
|
throw new \Exception("ID keranjang tidak ditemukan.");
|
||||||
// Kelompokkan produk berdasarkan Petani ID
|
|
||||||
$cartItems = [];
|
|
||||||
foreach ($cart as $id => $details) {
|
|
||||||
$produk = Produk::find($id);
|
|
||||||
if ($produk) {
|
|
||||||
$cartItems[$produk->petani_id][] = [
|
|
||||||
'produk' => $produk,
|
|
||||||
'qty' => $details['quantity']
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($cartItems as $petani_id => $items) {
|
$cartIds = explode(',', $request->cart_ids);
|
||||||
$subtotal_transaksi = 0;
|
|
||||||
$kode_invoice = 'INV/' . date('Ymd') . '/' . rand(1000, 9999);
|
|
||||||
|
|
||||||
// Membuat Header Transaksi per Petani
|
$cartItems = Cart::with('produk')
|
||||||
|
->whereIn('id', $cartIds)
|
||||||
|
->where('pembeli_id', $pembeli_id)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Kelompokkan produk berdasarkan Petani ID agar Invoice terpisah per toko
|
||||||
|
$groupedByPetani = [];
|
||||||
|
foreach ($cartItems as $item) {
|
||||||
|
$groupedByPetani[$item->produk->petani_id][] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($groupedByPetani as $petani_id => $items) {
|
||||||
$transaksi = Transaksi::create([
|
$transaksi = Transaksi::create([
|
||||||
'pembeli_id' => $pembeli_id,
|
'pembeli_id' => $pembeli_id,
|
||||||
'petani_id' => $petani_id,
|
'petani_id' => $petani_id,
|
||||||
'tanggal_transaksi' => now(),
|
'tanggal_transaksi' => now(),
|
||||||
'alamat_pengiriman' => $request->alamat_pengiriman,
|
'alamat_pengiriman' => $request->alamat_pengiriman,
|
||||||
'total_harga' => 0,
|
'total_harga' => 0, // Diupdate setelah menghitung subtotal
|
||||||
'status' => 'menunggu konfirmasi',
|
'status' => 'menunggu konfirmasi',
|
||||||
'kode_invoice' => $kode_invoice,
|
'kode_invoice' => 'INV/' . date('Ymd') . '/' . rand(1000, 9999),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$subtotal_transaksi = 0;
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$produk = $item['produk'];
|
$total_per_item = $item->produk->harga * $item->quantity;
|
||||||
$qty = $item['qty'];
|
|
||||||
$total_per_item = $produk->harga * $qty;
|
|
||||||
$subtotal_transaksi += $total_per_item;
|
$subtotal_transaksi += $total_per_item;
|
||||||
|
|
||||||
DetailTransaksi::create([
|
DetailTransaksi::create([
|
||||||
'transaksi_id' => $transaksi->id,
|
'transaksi_id' => $transaksi->id,
|
||||||
'produk_id' => $produk->id,
|
'produk_id' => $item->produk->id,
|
||||||
'jumlah' => $qty,
|
'jumlah' => $item->quantity,
|
||||||
'harga_satuan' => $produk->harga,
|
'harga_satuan' => $item->produk->harga,
|
||||||
'subtotal' => $total_per_item,
|
'subtotal' => $total_per_item,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$produk->decrement('stok', $qty);
|
$item->produk->decrement('stok', $item->quantity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update total harga transaksi
|
// Update total harga transaksi per petani
|
||||||
$transaksi->update(['total_harga' => $subtotal_transaksi]);
|
$transaksi->update(['total_harga' => $subtotal_transaksi]);
|
||||||
}
|
}
|
||||||
|
|
||||||
session()->forget('cart');
|
// OTOMATIS BERSIHKAN ITEM KERANJANG YANG SUDAH DIBELI
|
||||||
|
Cart::whereIn('id', $cartIds)->delete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return redirect()->route('pesanan.saya')->with('success', 'Pesanan berhasil dibuat! Menunggu konfirmasi petani.');
|
return redirect()->route('pesanan.saya')->with('success', 'Pesanan berhasil dibuat! Silakan pantau status pesanan Anda.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Riwayat Pesanan
|
// Riwayat Pesanan Pembeli
|
||||||
public function pesananSaya()
|
public function pesananSaya()
|
||||||
{
|
{
|
||||||
$transaksis = Transaksi::with(['detailTransaksis.produk.petani'])
|
$transaksis = Transaksi::with(['detailTransaksis.produk.petani'])
|
||||||
|
|
@ -172,11 +194,10 @@ public function konfirmasiSelesai($id)
|
||||||
$transaksi = Transaksi::where('pembeli_id', Auth::guard('pembeli')->id())
|
$transaksi = Transaksi::where('pembeli_id', Auth::guard('pembeli')->id())
|
||||||
->findOrFail($id);
|
->findOrFail($id);
|
||||||
|
|
||||||
// Hanya bisa selesai jika status sebelumnya 'dikirim'
|
|
||||||
if ($transaksi->status == 'dikirim') {
|
if ($transaksi->status == 'dikirim') {
|
||||||
$transaksi->status = 'selesai';
|
$transaksi->status = 'selesai';
|
||||||
$transaksi->save();
|
$transaksi->save();
|
||||||
return back()->with('success', 'Terima kasih! Pesanan telah diselesaikan.');
|
return back()->with('success', 'Terima kasih! Pesanan telah selesai.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return back()->with('error', 'Pesanan belum dikirim atau sudah selesai.');
|
return back()->with('error', 'Pesanan belum dikirim atau sudah selesai.');
|
||||||
|
|
@ -185,7 +206,7 @@ public function konfirmasiSelesai($id)
|
||||||
|
|
||||||
// --- FITUR PETANI ---
|
// --- FITUR PETANI ---
|
||||||
|
|
||||||
// Daftar Pesanan Masuk
|
// Daftar Pesanan Masuk untuk Dashboard Petani
|
||||||
public function pesananMasuk()
|
public function pesananMasuk()
|
||||||
{
|
{
|
||||||
$petaniId = Auth::guard('petani')->id();
|
$petaniId = Auth::guard('petani')->id();
|
||||||
|
|
@ -200,7 +221,7 @@ public function pesananMasuk()
|
||||||
return view('petani.pesanan.index', compact('pesanans'));
|
return view('petani.pesanan.index', compact('pesanans'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Status (Terima/Tolak/Kirim)
|
// Update Status Pesanan oleh Petani
|
||||||
public function updateStatus(Request $request, $id)
|
public function updateStatus(Request $request, $id)
|
||||||
{
|
{
|
||||||
$transaksi = Transaksi::findOrFail($id);
|
$transaksi = Transaksi::findOrFail($id);
|
||||||
|
|
@ -212,8 +233,9 @@ public function updateStatus(Request $request, $id)
|
||||||
$transaksi->status = $request->status;
|
$transaksi->status = $request->status;
|
||||||
$transaksi->save();
|
$transaksi->save();
|
||||||
|
|
||||||
|
// Jika dibatalkan, kembalikan stok produk
|
||||||
if ($request->status == 'batal') {
|
if ($request->status == 'batal') {
|
||||||
foreach ($transaksi->details as $detail) {
|
foreach ($transaksi->detailTransaksis as $detail) {
|
||||||
$detail->produk->increment('stok', $detail->jumlah);
|
$detail->produk->increment('stok', $detail->jumlah);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -221,12 +243,11 @@ public function updateStatus(Request $request, $id)
|
||||||
return back()->with('success', 'Status pesanan berhasil diperbarui.');
|
return back()->with('success', 'Status pesanan berhasil diperbarui.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail Pesanan (Petani)
|
// Detail Pesanan untuk Sisi Petani
|
||||||
public function pesananDetail($id)
|
public function pesananDetail($id)
|
||||||
{
|
{
|
||||||
$petaniId = Auth::guard('petani')->id();
|
$petaniId = Auth::guard('petani')->id();
|
||||||
|
|
||||||
// Ambil transaksi berdasarkan ID
|
|
||||||
$pesanan = Transaksi::whereHas('detailTransaksis.produk', function ($q) use ($petaniId) {
|
$pesanan = Transaksi::whereHas('detailTransaksis.produk', function ($q) use ($petaniId) {
|
||||||
$q->where('petani_id', $petaniId);
|
$q->where('petani_id', $petaniId);
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Laravolt\Indonesia\Models\City;
|
||||||
|
use Laravolt\Indonesia\Models\District;
|
||||||
|
use Laravolt\Indonesia\Models\Village;
|
||||||
|
|
||||||
|
class WilayahController extends Controller
|
||||||
|
{
|
||||||
|
public function getKota(Request $request)
|
||||||
|
{
|
||||||
|
$kota = City::where('province_code', $request->code)->get();
|
||||||
|
return response()->json($kota);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKecamatan(Request $request)
|
||||||
|
{
|
||||||
|
$kecamatan = District::where('city_code', $request->code)->get();
|
||||||
|
return response()->json($kecamatan);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDesa(Request $request)
|
||||||
|
{
|
||||||
|
$desa = Village::where('district_code', $request->code)->get();
|
||||||
|
return response()->json($desa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,11 @@ class Produk extends Model
|
||||||
'harga',
|
'harga',
|
||||||
'stok',
|
'stok',
|
||||||
'deskripsi',
|
'deskripsi',
|
||||||
'foto_produk'
|
'foto_produk',
|
||||||
|
'provinsi_code',
|
||||||
|
'kota_code',
|
||||||
|
'kecamatan_code',
|
||||||
|
'desa_code',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function petani()
|
public function petani()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/tinker": "^2.10.1"
|
"laravel/tinker": "^2.10.1",
|
||||||
|
"laravolt/indonesia": "^0.39.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "c514d8f7b9fc5970bdd94287905ef584",
|
"content-hash": "766a52f13bbfa552b799835b6f5f3e18",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
|
|
@ -1457,6 +1457,88 @@
|
||||||
},
|
},
|
||||||
"time": "2025-01-27T14:24:01+00:00"
|
"time": "2025-01-27T14:24:01+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "laravolt/indonesia",
|
||||||
|
"version": "v0.39",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/laravolt/indonesia.git",
|
||||||
|
"reference": "351e1c0e69b9415b0a56e03677fcfe0bbeca513a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/laravolt/indonesia/zipball/351e1c0e69b9415b0a56e03677fcfe0bbeca513a",
|
||||||
|
"reference": "351e1c0e69b9415b0a56e03677fcfe0bbeca513a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0",
|
||||||
|
"php": "^7.3|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"orchestra/testbench": "^6.0|^7.0|^8.0|^9.0|^10.0",
|
||||||
|
"php-coveralls/php-coveralls": "^2.1",
|
||||||
|
"phpunit/phpunit": "^9.0|^10.5|^11.5.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"laravolt/suitable": "Required if you want to access editor panel",
|
||||||
|
"spatie/geocoder": "Synchronize latitude longitude data directly using Google's Geocoding Service"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"aliases": {
|
||||||
|
"Indonesia": "Laravolt\\Indonesia\\Facade"
|
||||||
|
},
|
||||||
|
"providers": [
|
||||||
|
"Laravolt\\Indonesia\\ServiceProvider"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Laravolt\\Indonesia\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Bayu Hendra Winata",
|
||||||
|
"email": "bayu.hendra@javan.co.id"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Akbar Adhatama",
|
||||||
|
"email": "am.adhatama@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Deri Ramdani",
|
||||||
|
"email": "deri.ramdani1@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Package Laravel yang berisi data Provinsi, Kabupaten/Kota, Kecamatan, dan Keluarahan/Desa di seluruh Indonesia.",
|
||||||
|
"keywords": [
|
||||||
|
"desa",
|
||||||
|
"indonesia",
|
||||||
|
"kabupaten",
|
||||||
|
"kecamatan",
|
||||||
|
"kelurahan",
|
||||||
|
"kota",
|
||||||
|
"laravel",
|
||||||
|
"laravolt",
|
||||||
|
"provinsi"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravolt/indonesia/issues",
|
||||||
|
"source": "https://github.com/laravolt/indonesia/tree/v0.39"
|
||||||
|
},
|
||||||
|
"time": "2026-01-03T13:26:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "league/commonmark",
|
"name": "league/commonmark",
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'table_prefix' => 'indonesia_',
|
||||||
|
'route' => [
|
||||||
|
'enabled' => false,
|
||||||
|
'middleware' => ['web', 'auth'],
|
||||||
|
'prefix' => 'indonesia',
|
||||||
|
],
|
||||||
|
'view' => [
|
||||||
|
'layout' => 'ui::layouts.app',
|
||||||
|
],
|
||||||
|
'menu' => [
|
||||||
|
'enabled' => false,
|
||||||
|
],
|
||||||
|
'cache' => [
|
||||||
|
'ttl' => env('INDONESIA_CACHE_TTL', 3600),
|
||||||
|
'prefix' => env('INDONESIA_CACHE_PREFIX', 'indonesia_service'),
|
||||||
|
'store' => env('INDONESIA_CACHE_STORE', 'redis'),
|
||||||
|
],
|
||||||
|
'database' => [
|
||||||
|
'connection' => env('INDONESIA_DB_CONNECTION', null),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateProvincesTable extends Migration
|
||||||
|
{
|
||||||
|
protected function connection()
|
||||||
|
{
|
||||||
|
// New config (optional)
|
||||||
|
return config('indonesia.database.connection')
|
||||||
|
// Backward compatibility
|
||||||
|
?? config('database.default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::connection($this->connection())->create(config('laravolt.indonesia.table_prefix').'provinces', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->char('code', 2)->unique();
|
||||||
|
$table->string('name', 255);
|
||||||
|
$table->text('meta')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop(config('laravolt.indonesia.table_prefix').'provinces');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateCitiesTable extends Migration
|
||||||
|
{
|
||||||
|
protected function connection()
|
||||||
|
{
|
||||||
|
// New config (optional)
|
||||||
|
return config('indonesia.database.connection')
|
||||||
|
// Backward compatibility
|
||||||
|
?? config('database.default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::connection($this->connection())->create(config('laravolt.indonesia.table_prefix').'cities', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->char('code', 4)->unique();
|
||||||
|
$table->char('province_code', 2);
|
||||||
|
$table->string('name', 255);
|
||||||
|
$table->text('meta')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('province_code')
|
||||||
|
->references('code')
|
||||||
|
->on(config('laravolt.indonesia.table_prefix').'provinces')
|
||||||
|
->onUpdate('cascade')->onDelete('restrict');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop(config('laravolt.indonesia.table_prefix').'cities');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateDistrictsTable extends Migration
|
||||||
|
{
|
||||||
|
protected function connection()
|
||||||
|
{
|
||||||
|
// New config (optional)
|
||||||
|
return config('indonesia.database.connection')
|
||||||
|
// Backward compatibility
|
||||||
|
?? config('database.default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::connection($this->connection())->create(config('laravolt.indonesia.table_prefix').'districts', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->char('code', 7)->unique();
|
||||||
|
$table->char('city_code', 4);
|
||||||
|
$table->string('name', 255);
|
||||||
|
$table->text('meta')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('city_code')
|
||||||
|
->references('code')
|
||||||
|
->on(config('laravolt.indonesia.table_prefix').'cities')
|
||||||
|
->onUpdate('cascade')->onDelete('restrict');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop(config('laravolt.indonesia.table_prefix').'districts');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateVillagesTable extends Migration
|
||||||
|
{
|
||||||
|
protected function connection()
|
||||||
|
{
|
||||||
|
// New config (optional)
|
||||||
|
return config('indonesia.database.connection')
|
||||||
|
// Backward compatibility
|
||||||
|
?? config('database.default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::connection($this->connection())->create(config('laravolt.indonesia.table_prefix').'villages', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->char('code', 10)->unique();
|
||||||
|
$table->char('district_code', 7);
|
||||||
|
$table->string('name', 255);
|
||||||
|
$table->text('meta')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->foreign('district_code')
|
||||||
|
->references('code')
|
||||||
|
->on(config('laravolt.indonesia.table_prefix').'districts')
|
||||||
|
->onUpdate('cascade')->onDelete('restrict');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop(config('laravolt.indonesia.table_prefix').'villages');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('produks', function (Blueprint $table) {
|
||||||
|
if (Schema::hasColumn('produks', 'lokasi')) {
|
||||||
|
$table->dropColumn('lokasi');
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->char('provinsi_code', 2)->nullable()->after('deskripsi');
|
||||||
|
$table->char('kota_code', 4)->nullable()->after('provinsi_code');
|
||||||
|
$table->char('kecamatan_code', 7)->nullable()->after('kota_code');
|
||||||
|
$table->char('desa_code', 10)->nullable()->after('kecamatan_code');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('produks', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['provinsi_code', 'kota_code', 'kecamatan_code', 'desa_code']);
|
||||||
|
$table->string('lokasi')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -69,7 +69,7 @@ public function run(): void
|
||||||
'kode_invoice' => 'INV-' . $tahunIni . '03-003',
|
'kode_invoice' => 'INV-' . $tahunIni . '03-003',
|
||||||
'pembeli_id' => 1,
|
'pembeli_id' => 1,
|
||||||
'petani_id' => 1,
|
'petani_id' => 1,
|
||||||
'tanggal_transaksi' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
'tanggal_transaksi' => Carbon::create($tahunIni, 1, 5, 9, 15, 0),
|
||||||
'alamat_pengiriman' => 'Perumahan Indah Blok C2, Surabaya',
|
'alamat_pengiriman' => 'Perumahan Indah Blok C2, Surabaya',
|
||||||
'total_harga' => 150000,
|
'total_harga' => 150000,
|
||||||
'status' => 'selesai',
|
'status' => 'selesai',
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
|
@ -79,6 +79,7 @@
|
||||||
<a href="{{ route('cart') }}"
|
<a href="{{ route('cart') }}"
|
||||||
class="btn btn-outline-secondary py-2 rounded-pill">Kembali</a>
|
class="btn btn-outline-secondary py-2 rounded-pill">Kembali</a>
|
||||||
</div>
|
</div>
|
||||||
|
<input type="hidden" name="cart_ids" value="{{ request('cart_ids') }}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,9 @@
|
||||||
Platform langsung yang menghubungkan petani padi lokal dengan pembeli.
|
Platform langsung yang menghubungkan petani padi lokal dengan pembeli.
|
||||||
Dapatkan harga gabah terbaik dan gabah berkualitas.
|
Dapatkan harga gabah terbaik dan gabah berkualitas.
|
||||||
</p>
|
</p>
|
||||||
<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">
|
||||||
<i class="fas fa-shopping-bag me-2"></i> Belanja
|
<i class="fas fa-shopping-bag me-2"></i> Belanja
|
||||||
</a>
|
</a>
|
||||||
<a href="#katalog" class="btn btn-outline-secondary rounded-pill py-3 px-5">
|
|
||||||
Lihat Stok
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</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">
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Sidebar Kiri --- */
|
/* --- Sidebar Kiri --- */
|
||||||
.chat-sidebar {
|
.chat-sidebar {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -56,9 +57,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom Scrollbar */
|
/* Custom Scrollbar */
|
||||||
::-webkit-scrollbar { width: 5px; }
|
::-webkit-scrollbar {
|
||||||
::-webkit-scrollbar-track { background: transparent; }
|
width: 5px;
|
||||||
::-webkit-scrollbar-thumb { background: #ccc; border-radius: 10px; }
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #ccc;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
|
@ -71,36 +81,45 @@
|
||||||
|
|
||||||
{{-- KOLOM KIRI: DAFTAR PESAN --}}
|
{{-- KOLOM KIRI: DAFTAR PESAN --}}
|
||||||
<div class="col-md-4 chat-sidebar">
|
<div class="col-md-4 chat-sidebar">
|
||||||
<div class="sidebar-header">
|
{{-- Header Sidebar --}}
|
||||||
<input type="text" class="form-control bg-light border-0 rounded-pill px-3" placeholder="Cari pesan...">
|
<div class="p-3 border-bottom">
|
||||||
|
<h6 class="fw-bold text-dark mb-3">Pesan Masuk</h6>
|
||||||
|
<input type="text" class="form-control bg-light border-0 rounded-pill px-3"
|
||||||
|
placeholder="Cari percakapan...">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat-list-container">
|
{{-- List Chat --}}
|
||||||
<div class="list-group list-group-flush">
|
<div class="flex-grow-1 overflow-auto">
|
||||||
@forelse ($chatList as $chat)
|
@forelse ($chatList as $chat)
|
||||||
<a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}"
|
<a href="{{ route('pembeli.pesan.show', $chat['lawan_id']) }}"
|
||||||
class="list-group-item list-group-item-action chat-item py-3 border-0">
|
class="d-flex align-items-center p-3 text-decoration-none text-dark chat-item">
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
{{-- Avatar --}}
|
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle shadow-sm"
|
<img src="{{ asset('template/frontend/img/avatar.jpg') }}" class="rounded-circle shadow-sm"
|
||||||
width="50" height="50" style="object-fit: cover;">
|
width="45" height="45" style="object-fit: cover;">
|
||||||
|
|
||||||
|
{{-- Badge Merah Notifikasi --}}
|
||||||
@if($chat['unread'] > 0)
|
@if($chat['unread'] > 0)
|
||||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger border border-white">
|
<span
|
||||||
{{ $chat['unread'] }}
|
class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border border-light rounded-circle"></span>
|
||||||
</span>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Info Pesan --}}
|
|
||||||
<div class="ms-3 flex-grow-1 overflow-hidden">
|
<div class="ms-3 flex-grow-1 overflow-hidden">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
<h6 class="mb-0 text-dark fw-bold text-truncate">{{ $chat['nama'] }}</h6>
|
<span class="fw-bold small">{{ $chat['nama'] }}</span>
|
||||||
<small class="text-muted" style="font-size: 0.75rem;">{{ $chat['time'] }}</small>
|
<span class="text-muted" style="font-size: 0.7rem;">{{ $chat['time'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 text-muted text-truncate small">
|
<div class="d-flex justify-content-between align-items-center mt-1">
|
||||||
{{ Str::limit($chat['last_message'], 35) }}
|
<p class="mb-0 text-muted small text-truncate" style="max-width: 85%;">
|
||||||
|
{{ Str::limit($chat['last_message'], 25) }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
{{-- Angka Merah Notifikasi --}}
|
||||||
|
@if($chat['unread'] > 0)
|
||||||
|
<span class="badge bg-danger rounded-pill" style="font-size: 0.6rem;">{{ $chat['unread']
|
||||||
|
}}</span>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -112,7 +131,6 @@ class="list-group-item list-group-item-action chat-item py-3 border-0">
|
||||||
@endforelse
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{{-- KOLOM KANAN: PLACEHOLDER --}}
|
{{-- KOLOM KANAN: PLACEHOLDER --}}
|
||||||
<div class="col-md-8 d-none d-md-flex chat-placeholder">
|
<div class="col-md-8 d-none d-md-flex chat-placeholder">
|
||||||
|
|
@ -121,7 +139,8 @@ class="list-group-item list-group-item-action chat-item py-3 border-0">
|
||||||
<i class="fas fa-comments fa-4x text-success"></i>
|
<i class="fas fa-comments fa-4x text-success"></i>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="fw-bold text-dark">Selamat Datang di Chat</h5>
|
<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>
|
<p class="small">Pilih salah satu percakapan di sebelah kiri<br>untuk mulai berdiskusi dengan Petani.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,7 @@
|
||||||
|
|
||||||
@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>
|
||||||
<div class="row g-0 chat-layout shadow-lg">
|
<div class="row g-0 chat-layout shadow-lg">
|
||||||
|
|
||||||
{{-- SIDEBAR KIRI --}}
|
{{-- SIDEBAR KIRI --}}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,57 @@
|
||||||
{{-- SIDEBAR FILTER --}}
|
{{-- SIDEBAR FILTER --}}
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-3">
|
||||||
|
|
||||||
|
{{-- Filter Wilayah Lengkap--}}
|
||||||
|
<div class="card border-0 shadow-sm mb-4">
|
||||||
|
<div class="card-body p-4">
|
||||||
|
<h6 class="fw-bold mb-3 text-uppercase small text-muted">Filter Wilayah Lengkap</h6>
|
||||||
|
<form action="{{ route('shop') }}" method="GET">
|
||||||
|
@foreach(request()->only(['search', 'kategori', 'sort']) as $key => $val)
|
||||||
|
<input type="hidden" name="{{ $key }}" value="{{ $val }}">
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<div class="mb-2">
|
||||||
|
<label class="small fw-bold">Provinsi</label>
|
||||||
|
<select name="provinsi" id="filter_provinsi" class="form-select form-select-sm">
|
||||||
|
<option value="">Semua Provinsi</option>
|
||||||
|
@foreach(\Laravolt\Indonesia\Models\Province::all() as $prov)
|
||||||
|
<option value="{{ $prov->code }}" {{ request('provinsi')==$prov->code ? 'selected' : ''
|
||||||
|
}}>{{ $prov->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2">
|
||||||
|
<label class="small fw-bold">Kota/Kabupaten</label>
|
||||||
|
<select name="kota" id="filter_kota" class="form-select form-select-sm" {{
|
||||||
|
!request('provinsi') ? 'disabled' : '' }}>
|
||||||
|
<option value="">Semua Kota</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-2">
|
||||||
|
<label class="small fw-bold">Kecamatan</label>
|
||||||
|
<select name="kecamatan" id="filter_kecamatan" class="form-select form-select-sm" {{
|
||||||
|
!request('kota') ? 'disabled' : '' }}>
|
||||||
|
<option value="">Semua Kecamatan</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="small fw-bold">Desa</label>
|
||||||
|
<select name="desa" id="filter_desa" class="form-select form-select-sm" {{
|
||||||
|
!request('kecamatan') ? 'disabled' : '' }}>
|
||||||
|
<option value="">Semua Desa</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary btn-sm w-100 rounded-pill shadow-sm">
|
||||||
|
<i class="fas fa-search me-1"></i> Cari Produk
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{-- Card Kategori --}}
|
{{-- Card Kategori --}}
|
||||||
<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">
|
||||||
|
|
@ -73,7 +124,8 @@ class="d-flex justify-content-between align-items-center text-decoration-none {{
|
||||||
{{-- Top Bar (Info Jumlah & Sorting) --}}
|
{{-- 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 class="fw-bold text-dark">{{ $produks->firstItem() ?? 0 }}-{{ $produks->lastItem() ?? 0 }}</span>
|
Menampilkan <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>
|
||||||
|
|
||||||
|
|
@ -121,7 +173,8 @@ 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-primary 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 text-dark">{{ $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>
|
||||||
|
|
@ -165,6 +218,35 @@ class="card-img-top w-100 h-100" alt="{{ $produk->nama_produk }}"
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
function setupCascading(source, target, routeName, placeholder) {
|
||||||
|
$(source).on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$(target).html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if(target === '#filter_kota') {
|
||||||
|
$('#filter_kecamatan, #filter_desa').html('<option value="">Semua...</option>').prop('disabled', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.post("{{ url('/') }}/" + routeName, {code: code, _token: '{{ csrf_token() }}'}, function(data) {
|
||||||
|
$(target).html('<option value="">' + placeholder + '</option>').prop('disabled', false);
|
||||||
|
$.each(data, function(key, val) {
|
||||||
|
$(target).append(`<option value="${val.code}">${val.name}</option>`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupCascading('#filter_provinsi', '#filter_kota', 'get-kota', 'Semua Kota');
|
||||||
|
setupCascading('#filter_kota', '#filter_kecamatan', 'get-kecamatan', 'Semua Kecamatan');
|
||||||
|
setupCascading('#filter_kecamatan', '#filter_desa', 'get-desa', 'Semua Desa');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Hover Effect */
|
/* Hover Effect */
|
||||||
.product-card {
|
.product-card {
|
||||||
|
|
|
||||||
|
|
@ -231,12 +231,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{-- VERIFIKASI PETANI --}}
|
{{-- MENU VERIFIKASI PETANI DIHAPUS SESUAI REVISI --}}
|
||||||
<li class="sidebar-item {{ request()->is('admin/verifikasi*') ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.verifikasi.index') }}" class='sidebar-link'>
|
|
||||||
<i class="bi bi-person-badge-fill"></i> <span>Verifikasi Petani</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{{-- GAPOKTAN --}}
|
{{-- GAPOKTAN --}}
|
||||||
<li class="sidebar-item {{ request()->is('admin/gapoktan*') ? 'active' : '' }}">
|
<li class="sidebar-item {{ request()->is('admin/gapoktan*') ? 'active' : '' }}">
|
||||||
|
|
@ -256,6 +251,23 @@
|
||||||
|
|
||||||
{{-- Menu Dashboard Petani --}}
|
{{-- Menu Dashboard Petani --}}
|
||||||
@if (Auth::guard('petani')->check())
|
@if (Auth::guard('petani')->check())
|
||||||
|
{{-- LOGIC UNTUK MENGHITUNG NOTIFIKASI BADGE MERAH --}}
|
||||||
|
@php
|
||||||
|
$petaniId = Auth::guard('petani')->id();
|
||||||
|
|
||||||
|
// Hitung pesanan dengan status 'menunggu konfirmasi'
|
||||||
|
$notifPesanan = \App\Models\Transaksi::where('petani_id', $petaniId)
|
||||||
|
->where('status', 'menunggu konfirmasi')
|
||||||
|
->count();
|
||||||
|
|
||||||
|
// Hitung chat yang belum dibaca (sudah_dibaca = false)
|
||||||
|
// Asumsi penerima_type menggunakan namespace model penuh 'App\Models\Petani'
|
||||||
|
$notifPesan = \App\Models\Pesan::where('penerima_id', $petaniId)
|
||||||
|
->where('penerima_type', 'App\Models\Petani')
|
||||||
|
->where('sudah_dibaca', false)
|
||||||
|
->count();
|
||||||
|
@endphp
|
||||||
|
|
||||||
<li class="sidebar-item {{ request()->is('petani/dashboard') ? 'active' : '' }}">
|
<li class="sidebar-item {{ request()->is('petani/dashboard') ? 'active' : '' }}">
|
||||||
<a href="{{ route('petani.dashboard') }}" class='sidebar-link'>
|
<a href="{{ route('petani.dashboard') }}" class='sidebar-link'>
|
||||||
<i class="bi bi-grid-fill"></i> <span>Dashboard</span>
|
<i class="bi bi-grid-fill"></i> <span>Dashboard</span>
|
||||||
|
|
@ -266,15 +278,28 @@
|
||||||
<i class="bi bi-basket-fill"></i> <span>Kelola Produk</span>
|
<i class="bi bi-basket-fill"></i> <span>Kelola Produk</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
{{-- Menu Pesanan Masuk (Dengan Badge) --}}
|
||||||
<li class="sidebar-item {{ request()->is('petani/pesanan*') ? 'active' : '' }}">
|
<li class="sidebar-item {{ request()->is('petani/pesanan*') ? 'active' : '' }}">
|
||||||
<a href="{{ route('petani.pesanan.index') }}" class='sidebar-link'>
|
<a href="{{ route('petani.pesanan.index') }}" class='sidebar-link d-flex justify-content-between align-items-center'>
|
||||||
|
<div>
|
||||||
<i class="bi bi-receipt"></i> <span>Pesanan Masuk</span>
|
<i class="bi bi-receipt"></i> <span>Pesanan Masuk</span>
|
||||||
|
</div>
|
||||||
|
@if($notifPesanan > 0)
|
||||||
|
<span class="badge bg-danger rounded-pill">{{ $notifPesanan }}</span>
|
||||||
|
@endif
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
|
||||||
class="sidebar-item {{ request()->is('petani/pesan') || request()->is('petani/pesan/*') ? 'active' : '' }}">
|
{{-- Menu Kotak Masuk (Dengan Badge) --}}
|
||||||
<a href="{{ route('petani.pesan.index') }}" class='sidebar-link'>
|
<li class="sidebar-item {{ request()->is('petani/pesan') || request()->is('petani/pesan/*') ? 'active' : '' }}">
|
||||||
|
<a href="{{ route('petani.pesan.index') }}" class='sidebar-link d-flex justify-content-between align-items-center'>
|
||||||
|
<div>
|
||||||
<i class="bi bi-chat-dots-fill"></i> <span>Kotak Masuk</span>
|
<i class="bi bi-chat-dots-fill"></i> <span>Kotak Masuk</span>
|
||||||
|
</div>
|
||||||
|
@if($notifPesan > 0)
|
||||||
|
<span class="badge bg-danger rounded-pill">{{ $notifPesan }}</span>
|
||||||
|
@endif
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,12 @@
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1,
|
||||||
|
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);
|
||||||
|
|
@ -46,9 +51,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Utility Colors */
|
/* Utility Colors */
|
||||||
.text-primary { color: var(--primary-color) !important; }
|
.text-primary {
|
||||||
.bg-primary { background-color: var(--primary-color) !important; }
|
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 {
|
||||||
|
|
@ -144,7 +157,8 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<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">
|
<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">
|
||||||
<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>
|
||||||
|
|
||||||
|
|
@ -153,7 +167,8 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="d-flex justify-content-start 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 Mancon, Kecamatan Wilangan, Kabupaten Nganjuk</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>
|
</div>
|
||||||
|
|
@ -164,22 +179,27 @@
|
||||||
<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>
|
<h1 class="text-primary m-0 fw-bold" style="font-size: 1.8rem; letter-spacing: -1px;">
|
||||||
|
GriyaPadi.id</h1>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse">
|
<button class="navbar-toggler border-0" type="button" data-bs-toggle="collapse"
|
||||||
|
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('/') }}" class="nav-item nav-link mx-2 {{ request()->is('/') ? 'active' : '' }}">Home</a>
|
<a href="{{ url('/') }}"
|
||||||
<a href="{{ route('shop') }}" class="nav-item nav-link mx-2 {{ request()->is('shop*') ? 'active' : '' }}">Belanja</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>
|
||||||
</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-flex w-100 w-xl-auto mb-3 mb-xl-0">
|
<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">
|
<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') }}"
|
||||||
|
|
@ -193,7 +213,9 @@
|
||||||
|
|
||||||
<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>
|
<i class="bi bi-bag fs-4"></i>
|
||||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" style="font-size: 0.6rem;">
|
<span
|
||||||
|
class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"
|
||||||
|
style="font-size: 0.6rem;">
|
||||||
|
|
||||||
{{-- PERBAIKAN LOGIKA HITUNG CART --}}
|
{{-- PERBAIKAN LOGIKA HITUNG CART --}}
|
||||||
@if (Auth::guard('pembeli')->check())
|
@if (Auth::guard('pembeli')->check())
|
||||||
|
|
@ -207,20 +229,48 @@
|
||||||
|
|
||||||
@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="#" class="nav-link dropdown-toggle text-dark fw-bold d-flex align-items-center" data-bs-toggle="dropdown">
|
<a href="#"
|
||||||
<div class="bg-light rounded-circle d-flex align-items-center justify-content-center me-2" style="width: 35px; height: 35px;">
|
class="nav-link dropdown-toggle text-dark fw-bold d-flex align-items-center"
|
||||||
|
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 class="d-none d-xl-inline small">{{ Auth::guard('pembeli')->user()->nama_lengkap }}</span>
|
<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 class="bi bi-person me-2"></i> Profil</a>
|
<a href="{{ route('pembeli.profile') }}" class="dropdown-item py-2"><i
|
||||||
<a href="{{ route('pembeli.pesan.index') }}" class="dropdown-item py-2"><i class="bi bi-chat-dots me-2"></i> Pesan</a>
|
class="bi bi-person me-2"></i> Profil</a>
|
||||||
<a href="{{ route('pesanan.saya') }}" class="dropdown-item py-2"><i class="bi bi-bag-check me-2"></i> Riwayat Pesanan</a>
|
<a href="{{ route('pembeli.pesan.index') }}"
|
||||||
|
class="dropdown-item py-2 d-flex justify-content-between align-items-center">
|
||||||
|
<span><i class="bi bi-chat-dots me-2"></i> Pesan</span>
|
||||||
|
|
||||||
|
{{-- Logika Badge Notifikasi Pembeli --}}
|
||||||
|
@if (Auth::guard('pembeli')->check())
|
||||||
|
@php
|
||||||
|
$notifPesanPembeli = \App\Models\Pesan::where(
|
||||||
|
'penerima_id',
|
||||||
|
Auth::guard('pembeli')->id(),
|
||||||
|
)
|
||||||
|
->where('penerima_type', 'App\Models\Pembeli')
|
||||||
|
->where('sudah_dibaca', false)
|
||||||
|
->count();
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@if ($notifPesanPembeli > 0)
|
||||||
|
<span class="badge bg-danger rounded-pill"
|
||||||
|
style="font-size: 0.7rem;">{{ $notifPesanPembeli }}</span>
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
</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 class="bi bi-box-arrow-right me-2"></i> Logout</button>
|
<button type="submit" class="dropdown-item py-2 text-danger"><i
|
||||||
|
class="bi bi-box-arrow-right me-2"></i> Logout</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -237,10 +287,12 @@
|
||||||
<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" role="alert">
|
<div class="alert alert-success border-0 shadow-sm rounded-3 d-flex align-items-center"
|
||||||
|
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" aria-label="Close"></button>
|
<button type="button" class="btn-close ms-auto" data-bs-dismiss="alert"
|
||||||
|
aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -253,27 +305,37 @@
|
||||||
<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 produk berkualitas tinggi.</p>
|
<p class="mb-4 small">Menghubungkan petani lokal langsung dengan pembeli untuk harga yang adil dan
|
||||||
|
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 class="fab fa-twitter"></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 me-2" href=""><i class="fab fa-facebook-f"></i></a>
|
class="fab fa-twitter"></i></a>
|
||||||
<a class="btn btn-outline-light btn-sm rounded-circle" href=""><i class="fab fa-youtube"></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" 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 class="bi bi-chevron-right me-2 small"></i>Belanja</a>
|
<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="#"><i class="bi bi-chevron-right me-2 small"></i>Tentang Kami</a>
|
class="bi bi-chevron-right me-2 small"></i>Belanja</a>
|
||||||
<a class="text-white-50 text-decoration-none" href="#"><i class="bi bi-chevron-right me-2 small"></i>Hubungi Kami</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 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 class="bi bi-chevron-right me-2 small"></i>Profil</a>
|
<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('cart') }}"><i class="bi bi-chevron-right me-2 small"></i>Keranjang</a>
|
class="bi bi-chevron-right me-2 small"></i>Profil</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>
|
<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 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">
|
||||||
|
|
@ -286,12 +348,15 @@
|
||||||
</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">© <a href="#" class="text-white">GriyaPadi.id</a>, All Right Reserved.</span>
|
<span class="text-white-50 small">© <a href="#" class="text-white">GriyaPadi.id</a>, All
|
||||||
|
Right
|
||||||
|
Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="#" class="btn btn-primary btn-lg-square rounded-circle back-to-top shadow"><i class="bi bi-arrow-up"></i></a>
|
<a href="#" class="btn btn-primary btn-lg-square rounded-circle back-to-top shadow"><i
|
||||||
|
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>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
<select name="kategori_id" class="form-select" required>
|
<select name="kategori_id" class="form-select" required>
|
||||||
<option value="" disabled selected>Pilih Kategori</option>
|
<option value="" disabled selected>Pilih Kategori</option>
|
||||||
@foreach($kategoris as $kat)
|
@foreach($kategoris as $kat)
|
||||||
<option value="{{ $kat->id }}" {{ old('kategori_id') == $kat->id ? 'selected' : '' }}>
|
<option value="{{ $kat->id }}" {{ old('kategori_id')==$kat->id ? 'selected' : ''
|
||||||
|
}}>
|
||||||
{{ $kat->nama_kategori }}
|
{{ $kat->nama_kategori }}
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -51,6 +52,36 @@
|
||||||
<textarea name="deskripsi" class="form-control" rows="4"
|
<textarea name="deskripsi" class="form-control" rows="4"
|
||||||
placeholder="Jelaskan kualitas produk Anda..." required></textarea>
|
placeholder="Jelaskan kualitas produk Anda..." required></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Provinsi</label>
|
||||||
|
<select name="provinsi_code" id="provinsi" class="form-select" required>
|
||||||
|
<option value="">Pilih Provinsi</option>
|
||||||
|
@foreach ($provinsis as $prov)
|
||||||
|
<option value="{{ $prov->code }}">{{ $prov->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Kota / Kabupaten</label>
|
||||||
|
<select name="kota_code" id="kota" class="form-select" required disabled>
|
||||||
|
<option value="">Pilih Kota/Kabupaten</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Kecamatan</label>
|
||||||
|
<select name="kecamatan_code" id="kecamatan" class="form-select" required disabled>
|
||||||
|
<option value="">Pilih Kecamatan</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Desa / Kelurahan</label>
|
||||||
|
<select name="desa_code" id="desa" class="form-select" required disabled>
|
||||||
|
<option value="">Pilih Desa</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- UPLOAD GAMBAR --}}
|
{{-- UPLOAD GAMBAR --}}
|
||||||
|
|
@ -125,7 +156,84 @@ class="form-control form-control-sm" accept="image/*" multiple>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
// When Provinsi changes, fetch Kota
|
||||||
|
$('#provinsi').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#kota').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
$('#kecamatan').html('<option value="">== Pilih Kecamatan ==</option>').prop('disabled', true);
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.kota') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#kota').html('<option value="">== Pilih Kota/Kabupaten ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#kota').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#kota').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// When Kota changes, fetch Kecamatan
|
||||||
|
$('#kota').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#kecamatan').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.kecamatan') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#kecamatan').html('<option value="">== Pilih Kecamatan ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#kecamatan').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#kecamatan').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// When Kecamatan changes, fetch Desa
|
||||||
|
$('#kecamatan').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#desa').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.desa') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#desa').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#desa').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
// PREVIEW FOTO UTAMA
|
// PREVIEW FOTO UTAMA
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
|
|
@ -231,5 +339,8 @@ function updateBadge() {
|
||||||
countBadge.className = 'badge bg-primary rounded-pill';
|
countBadge.className = 'badge bg-primary rounded-pill';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -9,8 +9,7 @@
|
||||||
<div class="card border-0 shadow-sm">
|
<div class="card border-0 shadow-sm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{{-- Form Utama --}}
|
{{-- Form Utama --}}
|
||||||
<form action="{{ route('petani.produk.update', $produk->id) }}" method="POST"
|
<form action="{{ route('petani.produk.update', $produk->id) }}" method="POST" enctype="multipart/form-data">
|
||||||
enctype="multipart/form-data">
|
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
|
|
@ -20,8 +19,7 @@
|
||||||
<h5 class="mb-4">Informasi Produk</h5>
|
<h5 class="mb-4">Informasi Produk</h5>
|
||||||
<div class="form-group mb-3">
|
<div class="form-group mb-3">
|
||||||
<label class="fw-bold">Nama Produk</label>
|
<label class="fw-bold">Nama Produk</label>
|
||||||
<input type="text" name="nama_produk" class="form-control"
|
<input type="text" name="nama_produk" class="form-control" value="{{ $produk->nama_produk }}" required>
|
||||||
value="{{ $produk->nama_produk }}" required>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -30,7 +28,8 @@
|
||||||
<select name="kategori_id" class="form-select" required>
|
<select name="kategori_id" class="form-select" required>
|
||||||
<option value="" disabled>Pilih Kategori</option>
|
<option value="" disabled>Pilih Kategori</option>
|
||||||
@foreach($kategoris as $kat)
|
@foreach($kategoris as $kat)
|
||||||
<option value="{{ $kat->id }}" {{ (old('kategori_id', $produk->kategori_id) == $kat->id) ? 'selected' : '' }}>
|
<option value="{{ $kat->id }}" {{ (old('kategori_id', $produk->kategori_id) ==
|
||||||
|
$kat->id) ? 'selected' : '' }}>
|
||||||
{{ $kat->nama_kategori }}
|
{{ $kat->nama_kategori }}
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -39,21 +38,61 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label class="fw-bold">Stok</label>
|
<label class="fw-bold">Stok</label>
|
||||||
<input type="number" name="stok" class="form-control" value="{{ $produk->stok }}"
|
<input type="number" name="stok" class="form-control" value="{{ $produk->stok }}" required>
|
||||||
required>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
<div class="form-group mb-3">
|
||||||
<label class="fw-bold">Harga (Rp)</label>
|
<label class="fw-bold">Harga (Rp)</label>
|
||||||
<input type="number" name="harga" class="form-control" value="{{ $produk->harga }}"
|
<input type="number" name="harga" class="form-control" value="{{ $produk->harga }}" required>
|
||||||
required>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
<div class="form-group mb-3">
|
||||||
<label class="fw-bold">Deskripsi</label>
|
<label class="fw-bold">Deskripsi</label>
|
||||||
<textarea name="deskripsi" class="form-control" rows="4"
|
<textarea name="deskripsi" class="form-control" rows="4" required>{{ $produk->deskripsi }}</textarea>
|
||||||
required>{{ $produk->deskripsi }}</textarea>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Provinsi</label>
|
||||||
|
<select name="provinsi_code" id="provinsi" class="form-select" required>
|
||||||
|
<option value="">Pilih Provinsi</option>
|
||||||
|
@foreach ($provinsis as $prov)
|
||||||
|
<option value="{{ $prov->code }}" {{ $produk->provinsi_code == $prov->code ?
|
||||||
|
'selected' : '' }}>{{ $prov->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Kota / Kabupaten</label>
|
||||||
|
<select name="kota_code" id="kota" class="form-select" required>
|
||||||
|
<option value="">Pilih Kota/Kabupaten</option>
|
||||||
|
@foreach ($kotas as $kota)
|
||||||
|
<option value="{{ $kota->code }}" {{ $produk->kota_code == $kota->code ?
|
||||||
|
'selected' : '' }}>{{ $kota->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Kecamatan</label>
|
||||||
|
<select name="kecamatan_code" id="kecamatan" class="form-select" required>
|
||||||
|
<option value="">Pilih Kecamatan</option>
|
||||||
|
@foreach ($kecamatans as $kec)
|
||||||
|
<option value="{{ $kec->code }}" {{ $produk->kecamatan_code == $kec->code ?
|
||||||
|
'selected' : '' }}>{{ $kec->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label">Desa / Kelurahan</label>
|
||||||
|
<select name="desa_code" id="desa" class="form-select" required>
|
||||||
|
<option value="">Pilih Desa</option>
|
||||||
|
@foreach ($desas as $desa)
|
||||||
|
<option value="{{ $desa->code }}" {{ $produk->desa_code == $desa->code ?
|
||||||
|
'selected' : '' }}>{{ $desa->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -67,23 +106,18 @@
|
||||||
<label class="fw-bold mb-2">Foto Utama</label>
|
<label class="fw-bold mb-2">Foto Utama</label>
|
||||||
|
|
||||||
{{-- AREA PREVIEW --}}
|
{{-- AREA PREVIEW --}}
|
||||||
<div class="mb-2 bg-white border rounded d-flex align-items-center justify-content-center position-relative overflow-hidden"
|
<div class="mb-2 bg-white border rounded d-flex align-items-center justify-content-center position-relative overflow-hidden" style="height: 150px;">
|
||||||
style="height: 150px;">
|
|
||||||
|
|
||||||
<div id="placeholder-utama"
|
<div id="placeholder-utama" class="text-center text-muted {{ $produk->foto_produk ? 'd-none' : '' }}">
|
||||||
class="text-center text-muted {{ $produk->foto_produk ? 'd-none' : '' }}">
|
|
||||||
<i class="bi bi-cloud-arrow-up fs-1"></i>
|
<i class="bi bi-cloud-arrow-up fs-1"></i>
|
||||||
<div class="small mt-1">Upload foto baru</div>
|
<div class="small mt-1">Upload foto baru</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<img id="preview-utama"
|
<img id="preview-utama" src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : '#' }}" class="img-fluid w-100 h-100 object-fit-contain {{ $produk->foto_produk ? '' : 'd-none' }}">
|
||||||
src="{{ $produk->foto_produk ? asset('storage/' . $produk->foto_produk) : '#' }}"
|
|
||||||
class="img-fluid w-100 h-100 object-fit-contain {{ $produk->foto_produk ? '' : 'd-none' }}">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Input File --}}
|
{{-- Input File --}}
|
||||||
<input type="file" name="foto_produk" class="form-control form-control-sm"
|
<input type="file" name="foto_produk" class="form-control form-control-sm" accept="image/*" onchange="previewMainImage(this)">
|
||||||
accept="image/*" onchange="previewMainImage(this)">
|
|
||||||
<small class="text-muted">Biarkan kosong jika tidak ingin mengganti foto.</small>
|
<small class="text-muted">Biarkan kosong jika tidak ingin mengganti foto.</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -101,17 +135,11 @@ class="img-fluid w-100 h-100 object-fit-contain {{ $produk->foto_produk ? '' : '
|
||||||
|
|
||||||
{{-- Gambar Lama dari Database --}}
|
{{-- Gambar Lama dari Database --}}
|
||||||
@foreach($produk->images as $img)
|
@foreach($produk->images as $img)
|
||||||
<div class="col-4 position-relative existing-image-wrapper"
|
<div class="col-4 position-relative existing-image-wrapper" id="existing-img-{{ $img->id }}">
|
||||||
id="existing-img-{{ $img->id }}">
|
<img src="{{ asset('storage/' . $img->foto) }}" class="rounded w-100 border bg-white" style="height: 70px; object-fit: cover;">
|
||||||
<img src="{{ asset('storage/' . $img->foto) }}"
|
|
||||||
class="rounded w-100 border bg-white"
|
|
||||||
style="height: 70px; object-fit: cover;">
|
|
||||||
|
|
||||||
{{-- Tombol Hapus Gambar Lama --}}
|
{{-- Tombol Hapus Gambar Lama --}}
|
||||||
<a href="javascript:void(0)"
|
<a href="javascript:void(0)" class="position-absolute top-0 end-0 badge bg-danger text-white rounded-circle text-decoration-none m-1 shadow-sm" onclick="if(confirm('Hapus foto ini?')) deleteExistingImage({{ $img->id }});" style="cursor: pointer;">×</a>
|
||||||
class="position-absolute top-0 end-0 badge bg-danger text-white rounded-circle text-decoration-none m-1 shadow-sm"
|
|
||||||
onclick="if(confirm('Hapus foto ini?')) deleteExistingImage({{ $img->id }});"
|
|
||||||
style="cursor: pointer;">×</a>
|
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
@ -119,13 +147,11 @@ class="position-absolute top-0 end-0 badge bg-danger text-white rounded-circle t
|
||||||
|
|
||||||
{{-- INPUT FILE --}}
|
{{-- INPUT FILE --}}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<input type="file" id="input-gallery-visual"
|
<input type="file" id="input-gallery-visual" class="form-control form-control-sm" accept="image/*" multiple>
|
||||||
class="form-control form-control-sm" accept="image/*" multiple>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- INPUT FILE HIDDEN --}}
|
{{-- INPUT FILE HIDDEN --}}
|
||||||
<input type="file" name="foto_tambahan[]" id="real-input-gallery" class="d-none"
|
<input type="file" name="foto_tambahan[]" id="real-input-gallery" class="d-none" multiple>
|
||||||
multiple>
|
|
||||||
|
|
||||||
<small class="text-muted d-block" style="font-size: 0.8rem;">
|
<small class="text-muted d-block" style="font-size: 0.8rem;">
|
||||||
<i class="bi bi-info-circle me-1"></i>Maksimal 3 foto tambahan total.
|
<i class="bi bi-info-circle me-1"></i>Maksimal 3 foto tambahan total.
|
||||||
|
|
@ -143,8 +169,7 @@ class="form-control form-control-sm" accept="image/*" multiple>
|
||||||
|
|
||||||
{{-- FORM TERSEMBUNYI UNTUK HAPUS GAMBAR LAMA --}}
|
{{-- FORM TERSEMBUNYI UNTUK HAPUS GAMBAR LAMA --}}
|
||||||
@foreach($produk->images as $img)
|
@foreach($produk->images as $img)
|
||||||
<form id="form-del-img-{{ $img->id }}" action="{{ route('petani.produk.image.delete', $img->id) }}"
|
<form id="form-del-img-{{ $img->id }}" action="{{ route('petani.produk.image.delete', $img->id) }}" method="POST" style="display: none;">
|
||||||
method="POST" style="display: none;">
|
|
||||||
@csrf @method('DELETE')
|
@csrf @method('DELETE')
|
||||||
</form>
|
</form>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -153,7 +178,81 @@ class="form-control form-control-sm" accept="image/*" multiple>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#provinsi').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#kota').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
$('#kecamatan').html('<option value="">== Pilih Kecamatan ==</option>').prop('disabled', true);
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.kota') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#kota').html('<option value="">== Pilih Kota/Kabupaten ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#kota').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#kota').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#kota').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#kecamatan').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.kecamatan') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#kecamatan').html('<option value="">== Pilih Kecamatan ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#kecamatan').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#kecamatan').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#kecamatan').on('change', function() {
|
||||||
|
let code = $(this).val();
|
||||||
|
$('#desa').html('<option value="">Memuat...</option>').prop('disabled', true);
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
$.ajax({
|
||||||
|
url: "{{ route('get.desa') }}"
|
||||||
|
, type: "POST"
|
||||||
|
, data: {
|
||||||
|
code: code
|
||||||
|
, _token: '{{ csrf_token() }}'
|
||||||
|
}
|
||||||
|
, success: function(data) {
|
||||||
|
$('#desa').html('<option value="">== Pilih Desa ==</option>');
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
$('#desa').append('<option value="' + value.code + '">' + value.name + '</option>');
|
||||||
|
});
|
||||||
|
$('#desa').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
// PREVIEW FOTO UTAMA
|
// PREVIEW FOTO UTAMA
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
|
|
@ -262,5 +361,6 @@ function updateBadge() {
|
||||||
inputVisual.removeAttribute('title');
|
inputVisual.removeAttribute('title');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
@ -123,6 +123,11 @@
|
||||||
Route::put('/petani/profile', [ProfileController::class, 'updatePetani'])->name('petani.profile.update');
|
Route::put('/petani/profile', [ProfileController::class, 'updatePetani'])->name('petani.profile.update');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Route untuk Dropdown Wilayah Laravolt
|
||||||
|
Route::post('/get-kota', [\App\Http\Controllers\WilayahController::class, 'getKota'])->name('get.kota');
|
||||||
|
Route::post('/get-kecamatan', [\App\Http\Controllers\WilayahController::class, 'getKecamatan'])->name('get.kecamatan');
|
||||||
|
Route::post('/get-desa', [\App\Http\Controllers\WilayahController::class, 'getDesa'])->name('get.desa');
|
||||||
|
|
||||||
|
|
||||||
// --- CEK NIK GAPOKTAN AJAX ---
|
// --- CEK NIK GAPOKTAN AJAX ---
|
||||||
Route::post('/cek-nik-gapoktan', function (Request $request) {
|
Route::post('/cek-nik-gapoktan', function (Request $request) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue