feat: validasi AJAX NIK, relasi master Gapoktan, dan grafik pendapatan Chart.js di dashboard petani
This commit is contained in:
parent
c04507dfb4
commit
69a3234d0b
|
|
@ -48,7 +48,7 @@ public function loginProcess(Request $request)
|
|||
|
||||
Auth::guard('petani')->login($petani);
|
||||
$request->session()->regenerate();
|
||||
|
||||
|
||||
return redirect()->intended('petani/dashboard');
|
||||
}
|
||||
|
||||
|
|
@ -70,38 +70,49 @@ public function showRegisterForm()
|
|||
|
||||
public function registerProcess(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'role' => 'required|in:petani,pembeli',
|
||||
'nama_lengkap' => 'required',
|
||||
'email' => 'required|email',
|
||||
'username' => 'required|unique:petanis,username|unique:pembelis,username|alpha_dash',
|
||||
'password' => 'required|min:6',
|
||||
'no_hp' => 'required|numeric',
|
||||
'alamat' => 'required',
|
||||
$rules = [
|
||||
'role' => 'required|in:petani,pembeli',
|
||||
'nama_lengkap' => 'required',
|
||||
'email' => 'required|email',
|
||||
'username' => 'required|unique:petanis,username|unique:pembelis,username|alpha_dash',
|
||||
'password' => 'required|min:8',
|
||||
'no_hp' => 'required|numeric',
|
||||
'alamat' => 'required',
|
||||
];
|
||||
|
||||
if ($request->role == 'petani') {
|
||||
$rules['nik'] = 'required|exists:gapoktans,nik|unique:petanis,nik';
|
||||
}
|
||||
|
||||
$request->validate($rules, [
|
||||
'nik.required' => 'NIK wajib diisi untuk pendaftaran Petani.',
|
||||
'nik.exists' => 'NIK tidak terdaftar di sistem Admin/Gapoktan.',
|
||||
'nik.unique' => 'NIK ini sudah terdaftar pada akun lain.'
|
||||
]);
|
||||
|
||||
if ($request->role == 'petani') {
|
||||
Petani::create([
|
||||
'nik' => $request->nik,
|
||||
'nama_lengkap' => $request->nama_lengkap,
|
||||
'email' => $request->email,
|
||||
'username' => $request->username,
|
||||
'password' => Hash::make($request->password),
|
||||
'no_hp' => $request->no_hp,
|
||||
'alamat' => $request->alamat,
|
||||
'nama_usaha' => $request->nama_usaha ?? 'Toko Tani ' . $request->nama_lengkap,
|
||||
'status_akun' => 'menunggu'
|
||||
'email' => $request->email,
|
||||
'username' => $request->username,
|
||||
'password' => Hash::make($request->password),
|
||||
'no_hp' => $request->no_hp,
|
||||
'alamat' => $request->alamat,
|
||||
'nama_usaha' => $request->nama_usaha ?? 'Toko Tani ' . $request->nama_lengkap,
|
||||
'status_akun' => 'menunggu'
|
||||
]);
|
||||
|
||||
|
||||
return redirect('/login')->with('success', 'Registrasi Petani Berhasil! Mohon tunggu verifikasi Admin.');
|
||||
|
||||
} else {
|
||||
Pembeli::create([
|
||||
'nama_lengkap' => $request->nama_lengkap,
|
||||
'email' => $request->email,
|
||||
'username' => $request->username,
|
||||
'password' => Hash::make($request->password),
|
||||
'no_hp' => $request->no_hp,
|
||||
'alamat' => $request->alamat,
|
||||
'email' => $request->email,
|
||||
'username' => $request->username,
|
||||
'password' => Hash::make($request->password),
|
||||
'no_hp' => $request->no_hp,
|
||||
'alamat' => $request->alamat,
|
||||
]);
|
||||
|
||||
return redirect('/login')->with('success', 'Registrasi Berhasil! Silakan Login.');
|
||||
|
|
@ -111,9 +122,12 @@ public function registerProcess(Request $request)
|
|||
public function logout(Request $request)
|
||||
{
|
||||
// Logout semua guard untuk keamanan
|
||||
if (Auth::guard('admin')->check()) Auth::guard('admin')->logout();
|
||||
if (Auth::guard('petani')->check()) Auth::guard('petani')->logout();
|
||||
if (Auth::guard('pembeli')->check()) Auth::guard('pembeli')->logout();
|
||||
if (Auth::guard('admin')->check())
|
||||
Auth::guard('admin')->logout();
|
||||
if (Auth::guard('petani')->check())
|
||||
Auth::guard('petani')->logout();
|
||||
if (Auth::guard('pembeli')->check())
|
||||
Auth::guard('pembeli')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Gapoktan;
|
||||
|
||||
class GapoktanController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$gapoktan = Gapoktan::with('petanis')->get();
|
||||
return view('admin.gapoktan.index', compact('gapoktan'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'nik' => 'required|unique:gapoktans,nik|max:16',
|
||||
'nama' => 'required|string|max:255',
|
||||
], [
|
||||
'nik.unique' => 'NIK ini sudah terdaftar di sistem.',
|
||||
]);
|
||||
|
||||
Gapoktan::create([
|
||||
'nik' => $request->nik,
|
||||
'nama' => $request->nama,
|
||||
]);
|
||||
|
||||
return redirect()->back()->with('success', 'Data Gapoktan berhasil ditambahkan!');
|
||||
}
|
||||
|
||||
// Menghapus data
|
||||
public function destroy($id)
|
||||
{
|
||||
Gapoktan::findOrFail($id)->delete();
|
||||
return redirect()->back()->with('success', 'Data berhasil dihapus!');
|
||||
}
|
||||
}
|
||||
|
|
@ -5,39 +5,43 @@
|
|||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\Produk;
|
||||
use App\Models\DetailTransaksi;
|
||||
use App\Models\Transaksi;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$petaniId = Auth::guard('petani')->id();
|
||||
|
||||
// 1. Hitung Total Produk Aktif
|
||||
$totalProduk = Produk::where('petani_id', $petaniId)->count();
|
||||
$pesananBaru = Transaksi::where('petani_id', $petaniId)
|
||||
->where('status', 'dibayar')
|
||||
->count();
|
||||
|
||||
// 2. Hitung Pesanan Baru (Yang statusnya 'dibayar' / perlu diproses)
|
||||
$pesananBaru = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) {
|
||||
$q->where('petani_id', $petaniId);
|
||||
})->whereHas('transaksi', function($q) {
|
||||
$q->where('status', 'dibayar');
|
||||
})->count();
|
||||
$totalPemesanan = Transaksi::where('petani_id', $petaniId)
|
||||
->where('status', '!=', 'batal')
|
||||
->count();
|
||||
|
||||
// 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();
|
||||
$totalPendapatan = Transaksi::where('petani_id', $petaniId)
|
||||
->where('status', 'selesai')
|
||||
->sum('total_harga');
|
||||
|
||||
// 4. Hitung Total Pendapatan (Hanya yang status 'selesai')
|
||||
$totalPendapatan = DetailTransaksi::whereHas('produk', function($q) use ($petaniId) {
|
||||
$q->where('petani_id', $petaniId);
|
||||
})->whereHas('transaksi', function($q) {
|
||||
$q->where('status', 'selesai');
|
||||
})->sum('subtotal');
|
||||
$pendapatanPerBulan = Transaksi::where('petani_id', $petaniId)
|
||||
->where('status', 'selesai')
|
||||
->whereYear('tanggal_transaksi', date('Y'))
|
||||
->selectRaw('MONTH(tanggal_transaksi) as bulan, SUM(total_harga) as total')
|
||||
->groupBy('bulan')
|
||||
->pluck('total', 'bulan')
|
||||
->toArray();
|
||||
|
||||
return view('petani.dashboard', compact('totalProduk', 'pesananBaru', 'totalPemesanan', 'totalPendapatan'));
|
||||
$labels = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agt', 'Sep', 'Okt', 'Nov', 'Des'];
|
||||
$dataGrafik = [];
|
||||
|
||||
for ($i = 1; $i <= 12; $i++) {
|
||||
$dataGrafik[] = $pendapatanPerBulan[$i] ?? 0;
|
||||
}
|
||||
|
||||
return view('petani.dashboard', compact(
|
||||
'totalProduk', 'pesananBaru', 'totalPemesanan', 'totalPendapatan', 'labels', 'dataGrafik'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Gapoktan extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'gapoktans';
|
||||
|
||||
protected $fillable = [
|
||||
'nik',
|
||||
'nama',
|
||||
];
|
||||
|
||||
public function petanis()
|
||||
{
|
||||
return $this->hasOne(Petani::class, 'nik', 'nik');
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ class Petani extends Authenticatable implements CanResetPassword
|
|||
protected $table = 'petanis';
|
||||
|
||||
protected $fillable = [
|
||||
'nik',
|
||||
'nama_lengkap',
|
||||
'username',
|
||||
'email',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public function up(): void
|
|||
{
|
||||
Schema::create('petanis', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nik', 16)->nullable()->unique();
|
||||
$table->string('nama_lengkap');
|
||||
$table->string('username')->unique();
|
||||
$table->string('email')->unique();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?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('gapoktans', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('nik', 16)->unique();
|
||||
$table->string('nama');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('gapoktans');
|
||||
}
|
||||
};
|
||||
|
|
@ -19,9 +19,10 @@ public function run(): void
|
|||
// User::factory(10)->create();
|
||||
|
||||
$this->call([
|
||||
GapoktanSeeder::class,
|
||||
PetaniSeeder::class,
|
||||
AdminSeeder::class,
|
||||
PembeliSeeder::class,
|
||||
PetaniSeeder::class,
|
||||
ProdukSeeder::class,
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class GapoktanSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
DB::table('gapoktans')->insert([
|
||||
[
|
||||
'nik' => '3518012345678901',
|
||||
'nama' => 'Gapoktan Makmur Jaya',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'nik' => '3518012345678902',
|
||||
'nama' => 'Kelompok Tani Sumber Rejeki',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
[
|
||||
'nik' => '3518012345678903',
|
||||
'nama' => 'Gapoktan Suka Maju',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,11 +13,12 @@ class PetaniSeeder extends Seeder
|
|||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// Petani SUDAH AKTIF -> Bisa login & jualan
|
||||
// Petani SUDAH AKTIF
|
||||
DB::table('petanis')->insert([
|
||||
'nik' => '3518012345678901',
|
||||
'nama_lengkap' => 'Siti Aminah',
|
||||
'username' => 'siti_sayur',
|
||||
'email' => 'siti@gmail.com',
|
||||
'email' => 'siti@gmail.com',
|
||||
'password' => Hash::make('password123'),
|
||||
'no_hp' => '085678901234',
|
||||
'alamat' => 'Dusun Krajan RT 02 RW 01',
|
||||
|
|
@ -26,11 +27,13 @@ public function run(): void
|
|||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
// Petani BARU DAFTAR menunggu verifikasi
|
||||
DB::table('petanis')->insert([
|
||||
'nik' => '3518012345678902',
|
||||
'nama_lengkap' => 'Budi Santoso',
|
||||
'username' => 'budi_tani',
|
||||
'email' => 'budisantoso@gmail.com',
|
||||
'email' => 'budisantoso@gmail.com',
|
||||
'password' => Hash::make('password123'),
|
||||
'no_hp' => '081234567890',
|
||||
'alamat' => 'Jl. Raya Desa Sukamaju No. 12',
|
||||
|
|
@ -40,12 +43,12 @@ public function run(): void
|
|||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
|
||||
// Petani DITOLAK
|
||||
DB::table('petanis')->insert([
|
||||
'nik' => '3518012345678903',
|
||||
'nama_lengkap' => 'Joko Widodo',
|
||||
'username' => 'joko_tani',
|
||||
'email' => 'wiwokdetok@gmail.com',
|
||||
'email' => 'wiwokdetok@gmail.com',
|
||||
'password' => Hash::make('password123'),
|
||||
'no_hp' => '089876543210',
|
||||
'alamat' => 'Jl. Buntu No. 99',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class TransaksiSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$tahunIni = date('Y');
|
||||
|
||||
// ==========================================
|
||||
// TRANSAKSI 1: BULAN JANUARI (Selesai)
|
||||
// ==========================================
|
||||
$trx1 = DB::table('transaksis')->insertGetId([
|
||||
'kode_invoice' => 'INV-' . $tahunIni . '01-001',
|
||||
'pembeli_id' => 1,
|
||||
'petani_id' => 1,
|
||||
'tanggal_transaksi' => Carbon::create($tahunIni, 1, 15, 10, 0, 0),
|
||||
'alamat_pengiriman' => 'Jl. Raya Nganjuk No. 123, Jawa Timur',
|
||||
'total_harga' => 250000,
|
||||
'status' => 'selesai',
|
||||
'created_at' => Carbon::create($tahunIni, 1, 15, 10, 0, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 1, 15, 10, 0, 0),
|
||||
]);
|
||||
|
||||
DB::table('detail_transaksis')->insert([
|
||||
'transaksi_id' => $trx1,
|
||||
'produk_id' => 1,
|
||||
'jumlah' => 5,
|
||||
'harga_satuan' => 50000,
|
||||
'subtotal' => 250000,
|
||||
'created_at' => Carbon::create($tahunIni, 1, 15, 10, 0, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 1, 15, 10, 0, 0),
|
||||
]);
|
||||
|
||||
// ==========================================
|
||||
// TRANSAKSI 2: BULAN FEBRUARI (Selesai)
|
||||
// ==========================================
|
||||
$trx2 = DB::table('transaksis')->insertGetId([
|
||||
'kode_invoice' => 'INV-' . $tahunIni . '02-002',
|
||||
'pembeli_id' => 1,
|
||||
'petani_id' => 1,
|
||||
'tanggal_transaksi' => Carbon::create($tahunIni, 2, 10, 14, 30, 0),
|
||||
'alamat_pengiriman' => 'Jl. Sudirman No. 45, Jakarta',
|
||||
'total_harga' => 400000,
|
||||
'status' => 'selesai',
|
||||
'created_at' => Carbon::create($tahunIni, 2, 10, 14, 30, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 2, 10, 14, 30, 0),
|
||||
]);
|
||||
|
||||
DB::table('detail_transaksis')->insert([
|
||||
'transaksi_id' => $trx2,
|
||||
'produk_id' => 1,
|
||||
'jumlah' => 8,
|
||||
'harga_satuan' => 50000,
|
||||
'subtotal' => 400000,
|
||||
'created_at' => Carbon::create($tahunIni, 2, 10, 14, 30, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 2, 10, 14, 30, 0),
|
||||
]);
|
||||
|
||||
// ==========================================
|
||||
// TRANSAKSI 3: BULAN MARET (Selesai)
|
||||
// ==========================================
|
||||
$trx3 = DB::table('transaksis')->insertGetId([
|
||||
'kode_invoice' => 'INV-' . $tahunIni . '03-003',
|
||||
'pembeli_id' => 1,
|
||||
'petani_id' => 1,
|
||||
'tanggal_transaksi' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
||||
'alamat_pengiriman' => 'Perumahan Indah Blok C2, Surabaya',
|
||||
'total_harga' => 150000,
|
||||
'status' => 'selesai',
|
||||
'created_at' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
||||
]);
|
||||
|
||||
DB::table('detail_transaksis')->insert([
|
||||
'transaksi_id' => $trx3,
|
||||
'produk_id' => 1,
|
||||
'jumlah' => 3,
|
||||
'harga_satuan' => 50000,
|
||||
'subtotal' => 150000,
|
||||
'created_at' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
||||
'updated_at' => Carbon::create($tahunIni, 3, 5, 9, 15, 0),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
@extends('layouts.admin')
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<h3>Data Master Gapoktan</h3>
|
||||
|
||||
{{-- Pesan Sukses/Error --}}
|
||||
@if (session('success'))
|
||||
<div class="alert alert-success">{{ session('success') }}</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">{{ $errors->first() }}</div>
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
{{-- Form Tambah Data --}}
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">Tambah Data</div>
|
||||
<div class="card-body">
|
||||
<form action="{{ route('admin.gapoktan.store') }}" method="POST">
|
||||
@csrf
|
||||
<div class="form-group mb-3">
|
||||
<label>NIK</label>
|
||||
<input type="number" name="nik" class="form-control" required
|
||||
placeholder="Masukkan 16 digit NIK">
|
||||
</div>
|
||||
<div class="form-group mb-3">
|
||||
<label>Nama Petani / Kelompok</label>
|
||||
<input type="text" name="nama" class="form-control" required
|
||||
placeholder="Masukkan Nama">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Simpan</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Tabel Data --}}
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">Daftar NIK Terdaftar</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Tanggal Dibuat</th>
|
||||
<th>NIK</th>
|
||||
<th>Nama Petani/Kelompok</th>
|
||||
<th>Status Akun</th>
|
||||
<th>Aksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($gapoktan as $key => $item)
|
||||
<tr>
|
||||
<td>{{ $key + 1 }}</td>
|
||||
<td>{{ \Carbon\Carbon::parse($item->created_at)->translatedFormat('d F Y') }}</td>
|
||||
<td>{{ $item->nik }}</td>
|
||||
<td>{{ $item->nama }}</td>
|
||||
<td>
|
||||
@if ($item->petanis)
|
||||
<span class="badge bg-primary-green">Digunakan oleh
|
||||
{{ $item->petanis->nama_lengkap }}</span>
|
||||
@else
|
||||
<span class="badge bg-warning text-dark">Belum Digunakan</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<form action="{{ route('admin.gapoktan.destroy', $item->id) }}" method="POST"
|
||||
onsubmit="return confirm('Yakin hapus data ini?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-danger btn-sm">Hapus</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -41,15 +41,23 @@
|
|||
<table class="table table-borderless align-middle mb-0">
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold pt-3" width="30%">Nama Lengkap</td>
|
||||
<td class="pt-3 fw-bold text-dark fs-5">{{ $petani->nama_lengkap }}</td>
|
||||
<td class="pt-3 fw-medium">: {{ $petani->nama_lengkap }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold">Username</td>
|
||||
<td class="fw-medium">{{ $petani->username }}</td>
|
||||
<td class="fw-medium">: {{ $petani->username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold">Email</td>
|
||||
<td class="fw-medium">: {{ $petani->email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold">NIK Gapoktan</td>
|
||||
<td class="fw-medium">: {{ $petani->nik }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold">Nomor WhatsApp</td>
|
||||
<td>
|
||||
<td>:
|
||||
<span
|
||||
class="bg-light px-2 py-1 rounded fw-bold text-dark font-monospace">{{ $petani->no_hp }}</span>
|
||||
<a href="https://wa.me/{{ $petani->no_hp }}" target="_blank"
|
||||
|
|
@ -60,15 +68,15 @@ class="ms-2 text-decoration-none small text-success fw-bold">
|
|||
</tr>
|
||||
<tr>
|
||||
<td class="text-muted small text-uppercase fw-bold">Nama Usaha Tani</td>
|
||||
<td class="fw-medium">{{ $petani->nama_usaha }}</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>
|
||||
<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>
|
||||
<td class="text-secondary">: {{ $petani->created_at->format('d F Y, H:i') }} WIB</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
<p class="text-muted small">Gabung komunitas GriyaPadi.id</p>
|
||||
</div>
|
||||
|
||||
|
||||
<form action="{{ route('register.proses') }}" method="POST">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
|
|
@ -112,6 +113,13 @@
|
|||
<input type="email" name="email" class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3" id="wrapper-nik" style="display: none;">
|
||||
<label class="form-label small text-muted">NIK (Khusus Petani)</label>
|
||||
<input type="number" name="nik" id="nik" class="form-control"
|
||||
placeholder="Masukkan 16 digit NIK">
|
||||
<small id="pesan-nik" class="form-text d-block mt-1"></small>
|
||||
</div>
|
||||
|
||||
{{-- PASSWORD DENGAN VALIDASI --}}
|
||||
<div class="mb-2">
|
||||
<label class="form-label small text-muted">Password</label>
|
||||
|
|
@ -150,7 +158,7 @@
|
|||
</div>
|
||||
|
||||
<div class="d-grid mt-4">
|
||||
<button type="submit" class="btn btn-tani rounded-pill py-2">Register</button>
|
||||
<button type="submit" id="btn-daftar" class="btn btn-tani rounded-pill py-2">Register</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
|
@ -161,8 +169,9 @@ class="text-tani fw-bold text-decoration-none">Login</a></small>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
// Toggle Show/Hide Password
|
||||
// 1. Toggle Show/Hide Password
|
||||
function togglePassword(inputId, iconId) {
|
||||
const input = document.getElementById(inputId);
|
||||
const icon = document.getElementById(iconId);
|
||||
|
|
@ -177,14 +186,7 @@ function togglePassword(inputId, iconId) {
|
|||
}
|
||||
}
|
||||
|
||||
// Toggle Form Petani
|
||||
function toggleForm() {
|
||||
var role = document.getElementById('role').value;
|
||||
var formPetani = document.getElementById('form-petani');
|
||||
formPetani.style.display = (role === 'petani') ? 'block' : 'none';
|
||||
}
|
||||
|
||||
// Real-time Password Validator
|
||||
// 2. Real-time Password Validator (Yang tadi sempat hilang)
|
||||
function checkPassword() {
|
||||
const password = document.getElementById('password').value;
|
||||
|
||||
|
|
@ -212,6 +214,77 @@ function updateRequirement(id, isValid) {
|
|||
icon.classList.add('fa-times');
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Toggle Form Petani
|
||||
function toggleForm() {
|
||||
var role = document.getElementById('role').value;
|
||||
var formPetani = document.getElementById('form-petani');
|
||||
var wrapperNik = document.getElementById('wrapper-nik');
|
||||
var inputNik = document.getElementById('nik');
|
||||
var btnDaftar = document.getElementById('btn-daftar');
|
||||
|
||||
if (role === 'petani') {
|
||||
formPetani.style.display = 'block';
|
||||
wrapperNik.style.display = 'block';
|
||||
inputNik.setAttribute('required', 'required');
|
||||
} else {
|
||||
formPetani.style.display = 'none';
|
||||
wrapperNik.style.display = 'none';
|
||||
inputNik.removeAttribute('required');
|
||||
inputNik.value = '';
|
||||
$('#pesan-nik').text('');
|
||||
btnDaftar.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. AJAX Cek NIK
|
||||
$(document).ready(function() {
|
||||
toggleForm(); // Panggil saat web pertama dimuat
|
||||
|
||||
$('#nik').on('blur', function() {
|
||||
var currentRole = $('#role').val();
|
||||
if (currentRole !== 'petani') return; // Cuma jalan kalau rolenya petani
|
||||
|
||||
let nikValue = $(this).val();
|
||||
|
||||
if (nikValue === '') {
|
||||
$('#pesan-nik').text('');
|
||||
$('#btn-daftar').prop('disabled', false);
|
||||
return;
|
||||
}
|
||||
|
||||
$('#pesan-nik').text('Mengecek NIK...').css('color', 'blue');
|
||||
|
||||
// Jalankan AJAX
|
||||
$.ajax({
|
||||
url: "{{ route('cek.nik') }}",
|
||||
type: "POST",
|
||||
data: {
|
||||
_token: "{{ csrf_token() }}",
|
||||
nik: nikValue
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.status === 'tersedia') {
|
||||
$('#pesan-nik').text('NIK valid dan terdaftar.').css('color',
|
||||
'green');
|
||||
$('#btn-daftar').prop('disabled', false);
|
||||
} else if (response.status === 'sudah_dipakai') {
|
||||
$('#pesan-nik').text('NIK ini sudah terdaftar pada akun lain!').css(
|
||||
'color', 'orange');
|
||||
$('#btn-daftar').prop('disabled', true);
|
||||
} else {
|
||||
$('#pesan-nik').text(
|
||||
'NIK tidak terdaftar di Gapoktan! Anda tidak bisa mendaftar.'
|
||||
).css('color', 'red');
|
||||
$('#btn-daftar').prop('disabled', true);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$('#pesan-nik').text('Terjadi kesalahan server.').css('color', 'red');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
|||
|
|
@ -238,6 +238,13 @@
|
|||
</a>
|
||||
</li>
|
||||
|
||||
{{-- GAPOKTAN --}}
|
||||
<li class="sidebar-item {{ request()->is('admin/gapoktan*') ? 'active' : '' }}">
|
||||
<a href="{{ route('admin.gapoktan.index') }}" class='sidebar-link'>
|
||||
<i class="bi bi-people-fill"></i> <span>Data Gapoktan</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{{-- MONITORING --}}
|
||||
<li class="sidebar-item {{ request()->is('admin/monitoring*') ? 'active' : '' }}">
|
||||
<a href="{{ route('admin.monitoring') }}" class='sidebar-link'>
|
||||
|
|
@ -323,6 +330,8 @@ class='sidebar-link border-0 bg-transparent text-danger w-100 text-start'>
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@stack('scripts')
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/gh/zuramai/mazer@docs/demo/assets/static/js/components/dark.js"></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/gh/zuramai/mazer@docs/demo/assets/extensions/perfect-scrollbar/perfect-scrollbar.min.js">
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
@section('content')
|
||||
<section class="row">
|
||||
<div class="col-12 col-lg-12">
|
||||
|
||||
{{-- ROW 1: Card Ringkasan --}}
|
||||
<div class="row">
|
||||
{{-- Card 1: Produk Saya --}}
|
||||
<div class="col-6 col-lg-4 col-md-6">
|
||||
|
|
@ -24,7 +26,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Pemesanan --}}
|
||||
{{-- Card 2: Pemesanan --}}
|
||||
<div class="col-6 col-lg-4 col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body px-3 py-4-5">
|
||||
|
|
@ -43,7 +45,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Total Pendapatan --}}
|
||||
{{-- Card 3: Total Pendapatan --}}
|
||||
<div class="col-6 col-lg-4 col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-body px-3 py-4-5">
|
||||
|
|
@ -64,6 +66,20 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ROW 2: Grafik Pendapatan --}}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4>Grafik Pendapatan Tahun {{ date('Y') }}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="revenueChart" width="100%" height="30"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
|
|
@ -77,6 +93,65 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var ctx = document.getElementById("revenueChart").getContext('2d');
|
||||
|
||||
var revenueChart = new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: {!! json_encode($labels) !!},
|
||||
datasets: [{
|
||||
label: 'Pendapatan (Rp)',
|
||||
data: {!! json_encode($dataGrafik) !!},
|
||||
backgroundColor: '#57ca22',
|
||||
borderColor: '#4fac1d',
|
||||
borderWidth: 1,
|
||||
borderRadius: 5
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: {
|
||||
callback: function(value, index, values) {
|
||||
if(parseInt(value) >= 1000){
|
||||
return 'Rp ' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
||||
} else {
|
||||
return 'Rp ' + value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
let label = context.dataset.label || '';
|
||||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
if (context.parsed.y !== null) {
|
||||
label += 'Rp ' + context.parsed.y.toLocaleString('id-ID');
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -6,12 +6,16 @@
|
|||
use App\Http\Controllers\Admin\AdminController;
|
||||
use App\Http\Controllers\CartController;
|
||||
use App\Http\Controllers\ForgotPasswordController;
|
||||
use App\Http\Controllers\GapoktanController;
|
||||
use App\Http\Controllers\LandingController;
|
||||
use App\Http\Controllers\PesanController;
|
||||
use App\Http\Controllers\Petani\DashboardController;
|
||||
use App\Http\Controllers\Petani\ProdukController;
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use App\Http\Controllers\TransaksiController;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Gapoktan;
|
||||
use App\Models\Petani;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -82,20 +86,18 @@
|
|||
Route::middleware(['auth:admin'])->group(function () {
|
||||
Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
|
||||
Route::get('/admin/monitoring', [AdminController::class, 'monitoring'])->name('admin.monitoring');
|
||||
|
||||
// Petani Verification Logic
|
||||
Route::controller(AdminController::class)->prefix('admin/verifikasi')->group(function () {
|
||||
Route::get('/', 'verifikasiIndex')->name('admin.verifikasi.index');
|
||||
Route::get('/{id}', 'verifikasiShow')->name('admin.verifikasi.show');
|
||||
Route::post('/{id}/approve', 'verifikasiApprove');
|
||||
Route::post('/{id}/reject', 'verifikasiReject');
|
||||
});
|
||||
|
||||
// CRUD Kategori
|
||||
Route::resource('admin/kategori', KategoriController::class)->names('admin.kategori');
|
||||
|
||||
Route::get('/admin/transaksi/{id}', [AdminController::class, 'transaksiDetail'])
|
||||
->name('admin.transaksi.detail');
|
||||
Route::get('/admin/gapoktan', [GapoktanController::class, 'index'])->name('admin.gapoktan.index');
|
||||
Route::post('/admin/gapoktan', [GapoktanController::class, 'store'])->name('admin.gapoktan.store');
|
||||
Route::delete('/admin/gapoktan/{id}', [GapoktanController::class, 'destroy'])->name('admin.gapoktan.destroy');
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -120,3 +122,19 @@
|
|||
Route::get('/petani/profile', [ProfileController::class, 'editPetani'])->name('petani.profile');
|
||||
Route::put('/petani/profile', [ProfileController::class, 'updatePetani'])->name('petani.profile.update');
|
||||
});
|
||||
|
||||
|
||||
// --- CEK NIK GAPOKTAN AJAX ---
|
||||
Route::post('/cek-nik-gapoktan', function (Request $request) {
|
||||
$nik = $request->nik;
|
||||
$adaDiGapoktan = Gapoktan::where('nik', $nik)->exists();
|
||||
$sudahDipakai = Petani::where('nik', $nik)->exists();
|
||||
|
||||
if (!$adaDiGapoktan) {
|
||||
return response()->json(['status' => 'tidak_ditemukan']);
|
||||
} elseif ($sudahDipakai) {
|
||||
return response()->json(['status' => 'sudah_dipakai']);
|
||||
} else {
|
||||
return response()->json(['status' => 'tersedia']);
|
||||
}
|
||||
})->name('cek.nik');
|
||||
Loading…
Reference in New Issue