diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 5e778c9..59355a1 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -3,13 +3,36 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; -use App\Models\Petani; // Wajib import Model Petani +use App\Models\Petani; +use App\Models\Produk; +use App\Models\Transaksi; class AdminController extends Controller { public function dashboard() { - return view('admin.dashboard'); + $totalPetani = Petani::where('status_akun', 'aktif')->count(); + $petaniPending = Petani::where('status_akun', 'menunggu')->count(); + $totalProduk = Produk::count(); + $totalTransaksi = Transaksi::count(); + + $transaksiTerbaru = Transaksi::with(['pembeli', 'details'])->latest()->take(5)->get(); + + return view('admin.dashboard', compact( + 'totalPetani', + 'petaniPending', + 'totalProduk', + 'totalTransaksi', + 'transaksiTerbaru' + )); + } + + public function monitoring() + { + $produks = Produk::with('petani')->latest()->paginate(10); + $transaksis = Transaksi::with(['pembeli'])->latest()->paginate(10); + + return view('admin.monitoring', compact('produks', 'transaksis')); } public function verifikasiIndex() diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index cab79cf..be5e6ca 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -21,6 +21,9 @@ public function loginProcess(Request $request) $request->validate([ 'username' => 'required', 'password' => 'required', + ], [ + 'username.required' => 'Username wajib diisi', + 'password.required' => 'Password wajib diisi', ]); $credentials = $request->only('username', 'password'); @@ -31,34 +34,33 @@ public function loginProcess(Request $request) return redirect()->intended('admin/dashboard'); } - // Cek Login PEMBELI - if (Auth::guard('pembeli')->attempt($credentials)) { - $request->session()->regenerate(); - return redirect()->intended('/'); // Ke Halaman Utama (Landing) - } - // Cek Login PETANI $petani = Petani::where('username', $request->username)->first(); - // Jika username ada & password cocok if ($petani && Hash::check($request->password, $petani->password)) { - // Cek Status Akun + // Validasi Status Akun Petani if ($petani->status_akun == 'menunggu') { - return back()->withErrors(['username' => 'Akun Anda masih MENUNGGU persetujuan Admin.']); + return back()->withErrors(['login_error' => 'Akun Anda masih dalam proses verifikasi Admin.']); } if ($petani->status_akun == 'ditolak') { - return back()->withErrors(['username' => 'Maaf, pendaftaran Anda DITOLAK oleh Admin.']); + return back()->withErrors(['login_error' => 'Pendaftaran Anda ditolak. Silakan hubungi Admin.']); } - // Jika status Aktif, baru izinkan login Auth::guard('petani')->login($petani); $request->session()->regenerate(); + return redirect()->intended('petani/dashboard'); } + // Cek Login PEMBELI + if (Auth::guard('pembeli')->attempt($credentials)) { + $request->session()->regenerate(); + return redirect()->intended('/'); // Ke Landing Page + } + return back()->withErrors([ - 'username' => 'Username atau password salah.', - ]); + 'login_error' => 'Username atau password salah, atau akun tidak ditemukan.', + ])->withInput($request->only('username')); } public function showRegisterForm() @@ -68,13 +70,12 @@ public function showRegisterForm() public function registerProcess(Request $request) { - // Validasi $request->validate([ 'role' => 'required|in:petani,pembeli', 'nama_lengkap' => 'required', - 'username' => 'required|unique:petanis,username|unique:pembelis,username', + 'username' => 'required|unique:petanis,username|unique:pembelis,username|alpha_dash', 'password' => 'required|min:6', - 'no_hp' => 'required', + 'no_hp' => 'required|numeric', 'alamat' => 'required', ]); @@ -85,11 +86,11 @@ public function registerProcess(Request $request) 'password' => Hash::make($request->password), 'no_hp' => $request->no_hp, 'alamat' => $request->alamat, - 'nama_usaha' => $request->nama_usaha, + 'nama_usaha' => $request->nama_usaha ?? 'Toko Tani ' . $request->nama_lengkap, 'status_akun' => 'menunggu' ]); - return redirect('/login')->with('success', 'Pendaftaran Berhasil! Tunggu verifikasi Admin untuk Login.'); + return redirect('/login')->with('success', 'Registrasi Petani Berhasil! Mohon tunggu verifikasi Admin.'); } else { Pembeli::create([ @@ -100,15 +101,16 @@ public function registerProcess(Request $request) 'alamat' => $request->alamat, ]); - return redirect('/login')->with('success', 'Pendaftaran Berhasil! Silakan Login.'); + return redirect('/login')->with('success', 'Registrasi Berhasil! Silakan Login.'); } } public function logout(Request $request) { + // Logout semua guard untuk keamanan if (Auth::guard('admin')->check()) Auth::guard('admin')->logout(); - elseif (Auth::guard('petani')->check()) Auth::guard('petani')->logout(); - elseif (Auth::guard('pembeli')->check()) Auth::guard('pembeli')->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(); diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php new file mode 100644 index 0000000..f3cf215 --- /dev/null +++ b/app/Http/Controllers/ProfileController.php @@ -0,0 +1,89 @@ +user(); + return view('petani.profile', compact('user')); + } + + public function updatePetani(Request $request) + { + $user = Auth::guard('petani')->user(); + + $request->validate([ + 'nama_lengkap' => 'required|string|max:255', + 'email' => 'required|email|unique:petanis,email,' . $user->id, + 'password' => 'nullable|min:6|confirmed', + 'foto' => 'nullable|image|max:2048' + ]); + + $user->nama_lengkap = $request->nama_lengkap; + $user->email = $request->email; + + if ($request->filled('password')) { + $user->password = Hash::make($request->password); + } + + if ($request->hasFile('foto')) { + if ($user->foto && Storage::exists('public/' . $user->foto)) { + Storage::delete('public/' . $user->foto); + } + $path = $request->file('foto')->store('avatars', 'public'); + $user->foto = $path; + } + + $user->save(); + return back()->with('success', 'Profil berhasil diperbarui!'); + } + + // --- FITUR PEMBELI --- + public function editPembeli() + { + $user = Auth::guard('pembeli')->user(); + return view('landing.profile', compact('user')); + } + + public function updatePembeli(Request $request) + { + $user = Auth::guard('pembeli')->user(); + + $request->validate([ + 'nama_lengkap' => 'required|string|max:255', + 'email' => 'required|email|unique:pembelis,email,' . $user->id, + 'no_hp' => 'required|string', + 'alamat' => 'required|string', + 'password' => 'nullable|min:6|confirmed', + 'foto' => 'nullable|image|max:2048' + ]); + + $user->nama_lengkap = $request->nama_lengkap; + $user->email = $request->email; + $user->no_hp = $request->no_hp; + $user->alamat = $request->alamat; + + if ($request->filled('password')) { + $user->password = Hash::make($request->password); + } + + if ($request->hasFile('foto')) { + if ($user->foto && Storage::exists('public/' . $user->foto)) { + Storage::delete('public/' . $user->foto); + } + $path = $request->file('foto')->store('avatars', 'public'); + $user->foto = $path; + } + + $user->save(); + return back()->with('success', 'Profil berhasil diperbarui!'); + } +} diff --git a/app/Models/Pembeli.php b/app/Models/Pembeli.php index 1ef0942..8163fe2 100644 --- a/app/Models/Pembeli.php +++ b/app/Models/Pembeli.php @@ -14,6 +14,7 @@ class Pembeli extends Authenticatable protected $fillable = [ 'nama_lengkap', 'username', + 'email', 'password', 'no_hp', 'alamat' diff --git a/app/Models/Petani.php b/app/Models/Petani.php index f1b3b64..7397fc9 100644 --- a/app/Models/Petani.php +++ b/app/Models/Petani.php @@ -14,6 +14,7 @@ class Petani extends Authenticatable protected $fillable = [ 'nama_lengkap', 'username', + 'email', 'password', 'no_hp', 'alamat', diff --git a/database/migrations/2025_11_25_123427_create_petanis_table.php b/database/migrations/2025_11_25_123427_create_petanis_table.php index 08b8a8d..4ae2fd1 100644 --- a/database/migrations/2025_11_25_123427_create_petanis_table.php +++ b/database/migrations/2025_11_25_123427_create_petanis_table.php @@ -10,22 +10,21 @@ * Run the migrations. */ public function up(): void -{ - Schema::create('petanis', function (Blueprint $table) { - $table->id(); - $table->string('nama_lengkap'); - $table->string('username')->unique(); - $table->string('password'); - $table->string('no_hp', 15); - $table->text('alamat'); - $table->string('nama_usaha')->nullable(); - - // Status Verifikasi - $table->enum('status_akun', ['menunggu', 'aktif', 'ditolak'])->default('menunggu'); - - $table->timestamps(); - }); -} + { + Schema::create('petanis', function (Blueprint $table) { + $table->id(); + $table->string('nama_lengkap'); + $table->string('username')->unique(); + $table->string('email')->unique(); + $table->string('password'); + $table->string('foto')->nullable(); + $table->string('no_hp', 15); + $table->text('alamat'); + $table->string('nama_usaha')->nullable(); + $table->enum('status_akun', ['menunggu', 'aktif', 'ditolak'])->default('menunggu'); + $table->timestamps(); + }); + } /** * Reverse the migrations. diff --git a/database/migrations/2025_11_25_123428_create_pembelis_table.php b/database/migrations/2025_11_25_123428_create_pembelis_table.php index 399368f..dba5eda 100644 --- a/database/migrations/2025_11_25_123428_create_pembelis_table.php +++ b/database/migrations/2025_11_25_123428_create_pembelis_table.php @@ -10,17 +10,19 @@ * Run the migrations. */ public function up(): void -{ - Schema::create('pembelis', function (Blueprint $table) { - $table->id(); - $table->string('nama_lengkap'); - $table->string('username')->unique(); - $table->string('password'); - $table->string('no_hp', 15); - $table->text('alamat'); - $table->timestamps(); - }); -} + { + Schema::create('pembelis', function (Blueprint $table) { + $table->id(); + $table->string('nama_lengkap'); + $table->string('username')->unique(); + $table->string('email')->unique(); + $table->string('password'); + $table->string('foto')->nullable(); + $table->string('no_hp', 15); + $table->text('alamat'); + $table->timestamps(); + }); + } /** * Reverse the migrations. diff --git a/database/seeders/PembeliSeeder.php b/database/seeders/PembeliSeeder.php index 61a9fbd..bd0f902 100644 --- a/database/seeders/PembeliSeeder.php +++ b/database/seeders/PembeliSeeder.php @@ -17,6 +17,7 @@ public function run(): void [ 'nama_lengkap' => 'Andi Pembeli', 'username' => 'andi_beli', + 'email' => 'andiwibu@gmail.com', 'password' => Hash::make('password123'), 'no_hp' => '081298765432', 'alamat' => 'Jl. Merdeka No. 45, Kota Sejahtera', @@ -26,6 +27,7 @@ public function run(): void [ 'nama_lengkap' => 'Rina Suka Sayur', 'username' => 'rina_sayur', + 'email' => 'rinauhuy@gmail.com', 'password' => Hash::make('password123'), 'no_hp' => '085612345678', 'alamat' => 'Perumahan Griya Asri Blok B2, Desa Sukamaju', diff --git a/database/seeders/PetaniSeeder.php b/database/seeders/PetaniSeeder.php index 2264998..9791a04 100644 --- a/database/seeders/PetaniSeeder.php +++ b/database/seeders/PetaniSeeder.php @@ -17,6 +17,7 @@ public function run(): void DB::table('petanis')->insert([ 'nama_lengkap' => 'Budi Santoso', 'username' => 'budi_tani', + 'email' => 'budisantoso@gmail.com', 'password' => Hash::make('password123'), 'no_hp' => '081234567890', 'alamat' => 'Jl. Raya Desa Sukamaju No. 12', @@ -30,6 +31,7 @@ public function run(): void DB::table('petanis')->insert([ 'nama_lengkap' => 'Siti Aminah', 'username' => 'siti_sayur', + 'email' => 'siti@gmail.com', 'password' => Hash::make('password123'), 'no_hp' => '085678901234', 'alamat' => 'Dusun Krajan RT 02 RW 01', @@ -43,6 +45,7 @@ public function run(): void DB::table('petanis')->insert([ 'nama_lengkap' => 'Joko Widodo', 'username' => 'joko_tani', + 'email' => 'wiwokdetok@gmail.com', 'password' => Hash::make('password123'), 'no_hp' => '089876543210', 'alamat' => 'Jl. Buntu No. 99', diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 48c49ed..1099e1d 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -1,23 +1,126 @@ @extends('layouts.admin') @section('title', 'Dashboard Admin') -@section('page-title', 'Dashboard Admin Desa') +@section('page-title', 'Overview Sistem') @section('content') -
-
-

Selamat Datang, {{ Auth::guard('admin')->user()->nama }}!

-
-
-

Anda login sebagai Administrator Desa.

- -
- Silakan cek menu Verifikasi Petani untuk melihat pendaftaran baru. +
+
+
+ {{-- Statistik Petani Aktif --}} +
+
+
+
+
+
+
+
+
Petani Aktif
+
{{ $totalPetani }}
+
+
+
+
+
+ + {{-- Statistik Menunggu Verifikasi --}} +
+
+
+
+
+
+
+
+
Verifikasi Pending
+
{{ $petaniPending }}
+
+
+
+
+
+ + {{-- Statistik Total Produk --}} +
+
+
+
+
+
+
+
+
Total Produk
+
{{ $totalProduk }}
+
+
+
+
+
+ + {{-- Statistik Total Transaksi --}} +
+
+
+
+
+
+
+
+
Total Transaksi
+
{{ $totalTransaksi }}
+
+
+
+
+
- - Buka Halaman Verifikasi - + {{-- Tabel Ringkasan Transaksi Terbaru --}} +
+
+
+
+

Transaksi Terbaru di Platform

+
+
+
+ + + + + + + + + + + + @forelse($transaksiTerbaru as $trx) + + + + + + + + @empty + + @endforelse + +
InvoicePembeliTotalStatusTanggal
#{{ $trx->kode_invoice }}{{ $trx->pembeli->nama_lengkap }}Rp {{ number_format($trx->total_harga, 0, ',', '.') }} + + {{ ucfirst($trx->status) }} + + {{ $trx->created_at->diffForHumans() }}
Belum ada transaksi.
+
+ +
+
+
+
-
+ @endsection \ No newline at end of file diff --git a/resources/views/admin/monitoring.blade.php b/resources/views/admin/monitoring.blade.php index e69de29..b0f799b 100644 --- a/resources/views/admin/monitoring.blade.php +++ b/resources/views/admin/monitoring.blade.php @@ -0,0 +1,78 @@ +@extends('layouts.admin') + +@section('title', 'Monitoring Sistem') +@section('page-title', 'Monitoring Data') + +@section('content') +
+ {{-- TABEL SEMUA TRANSAKSI --}} +
+
+
+

Semua Transaksi

+
+
+
+ + + + + + + + + + + + @foreach($transaksis as $t) + + + + + + + + @endforeach + +
InvoicePembeliTotalStatusWaktu
{{ $t->kode_invoice }}{{ $t->pembeli->nama_lengkap }}Rp {{ number_format($t->total_harga, 0, ',', '.') }}{{ strtoupper($t->status) }}{{ $t->created_at->format('d M Y H:i') }}
+
+ {{ $transaksis->links() }} +
+
+
+ + {{-- TABEL SEMUA PRODUK --}} +
+
+
+

Semua Produk Terdaftar

+
+
+
+ + + + + + + + + + + @foreach($produks as $p) + + + + + + + @endforeach + +
Nama ProdukPemilik (Petani)HargaStok
{{ $p->nama_produk }}{{ $p->petani->nama_lengkap }}Rp {{ number_format($p->harga, 0, ',', '.') }}{{ $p->stok }}
+
+ {{ $produks->links() }} +
+
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 5ecc482..90fe3e9 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -1,61 +1,106 @@ + - Login - TaniDesa - - + Masuk - TaniDesa + + + + + -
-
-
-
- -

Log in

- {{-- Pesan Sukses Register --}} - @if (session('success')) -
{{ session('success') }}
- @endif - - {{-- Pesan Error Login --}} - @if ($errors->any()) -
-
    - @foreach ($errors->all() as $error) -
  • {{ $error }}
  • - @endforeach -
-
- @endif - -
- @csrf -
- -
-
-
- -
-
- -
-
-

Belum punya akun? Daftar.

-
-
+
+
+
+ +

TaniDesa

+
+

Masuk untuk melanjutkan

-
-
+ + {{-- Pesan Sukses --}} + @if (session('success')) + + @endif + + {{-- Pesan Error --}} + @if ($errors->any()) +
+
    + @foreach ($errors->all() as $error) +
  • {{ $error }}
  • + @endforeach +
+
+ @endif + +
+ @csrf +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+ +
+ Belum punya akun? Daftar
+ \ No newline at end of file diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index cd3a0df..97d0af4 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -1,72 +1,117 @@ + Daftar - TaniDesa - - + + + + + -
-
-
-
-

Daftar.

-

Bergabunglah dengan komunitas TaniDesa.

-
- @csrf - -
- - -
+
+
+
+ +

Daftar Akun

+
+

Bergabunglah dengan TaniDesa

+
-
- -
-
+ + @csrf + + {{-- Pilihan Role --}} +
+ + +
-
- -
-
- -
- -
-
- -
- -
-
- -
- -
-
- - {{-- Input Khusus Petani (Hidden Awal) --}} - - - - -
-

Sudah punya akun? Login.

+
+
+ + +
+
+ +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + {{-- Input Khusus Petani --}} + + +
+ +
+ + +
+ Sudah punya akun? Login
diff --git a/resources/views/landing/profile.blade.php b/resources/views/landing/profile.blade.php new file mode 100644 index 0000000..a8c3faa --- /dev/null +++ b/resources/views/landing/profile.blade.php @@ -0,0 +1,82 @@ +@extends('layouts.frontend') + +@section('title', 'Profil Saya') + +@section('content') +
+
+
+
+
+

Edit Profil

+
+
+ @if (session('success')) +
{{ session('success') }}
+ @endif + +
+ @csrf + @method('PUT') + +
+
+ +
+ +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+

Isi kolom di bawah HANYA jika ingin mengganti password.

+ +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+
+
+
+
+
+
+@endsection diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index e88abd4..e0e67c2 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -22,7 +22,6 @@
-
diff --git a/resources/views/petani/profile.blade.php b/resources/views/petani/profile.blade.php new file mode 100644 index 0000000..2888aba --- /dev/null +++ b/resources/views/petani/profile.blade.php @@ -0,0 +1,63 @@ +@extends('layouts.admin') + +@section('title', 'Profil Saya') +@section('page-title', 'Pengaturan Akun') + +@section('content') +
+
+ @if (session('success')) +
{{ session('success') }}
+ @endif + +
+ @csrf + @method('PUT') + +
+
+ Avatar + +
+ +
+
+ +
+
+ + +
+
+ + +
+ +
+
Ganti Password (Opsional)
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+@endsection diff --git a/routes/web.php b/routes/web.php index efb6927..3dcb69e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,6 +8,7 @@ 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; /* @@ -65,12 +66,16 @@ // Route Pesan untuk Pembeli Route::get('/pesan', [PesanController::class, 'index'])->name('pembeli.pesan.index'); Route::get('/pesan/{id}', [PesanController::class, 'show'])->name('pembeli.pesan.show'); + + Route::get('/profile', [ProfileController::class, 'editPembeli'])->name('pembeli.profile'); + Route::put('/profile', [ProfileController::class, 'updatePembeli'])->name('pembeli.profile.update'); }); // --- ADMIN AREA --- 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 () { @@ -98,4 +103,7 @@ // Route Pesan untuk Petani Route::get('/petani/pesan', [PesanController::class, 'index'])->name('petani.pesan.index'); Route::get('/petani/pesan/{id}', [PesanController::class, 'show'])->name('petani.pesan.show'); + + Route::get('/petani/profile', [ProfileController::class, 'editPetani'])->name('petani.profile'); + Route::put('/petani/profile', [ProfileController::class, 'updatePetani'])->name('petani.profile.update'); });