diff --git a/app/Http/Controllers/PesanController.php b/app/Http/Controllers/PesanController.php new file mode 100644 index 0000000..4da0108 --- /dev/null +++ b/app/Http/Controllers/PesanController.php @@ -0,0 +1,113 @@ +getAuthenticatedUser(); + $isPetani = Auth::guard('petani')->check(); + + $allMessages = Pesan::where(function ($q) use ($user) { + $q->where('pengirim_id', $user->id)->where('pengirim_type', get_class($user)); + })->orWhere(function ($q) use ($user) { + $q->where('penerima_id', $user->id)->where('penerima_type', get_class($user)); + })->orderBy('created_at', 'desc')->get(); + + // Kelompokkan berdasarkan ID Lawan Bicara + $conversations = $allMessages->groupBy(function ($pesan) use ($user) { + return $pesan->pengirim_id == $user->id + ? $pesan->penerima_type . '_' . $pesan->penerima_id + : $pesan->pengirim_type . '_' . $pesan->pengirim_id; + }); + + // Format data untuk view + $chatList = $conversations->map(function ($msgs) use ($user) { + $lastMsg = $msgs->first(); + + // Tentukan siapa lawan bicaranya + if ($lastMsg->pengirim_id == $user->id) { + $lawan = $lastMsg->penerima; + } else { + $lawan = $lastMsg->pengirim; + } + + return [ + 'lawan_id' => $lawan->id ?? 0, + 'lawan_type' => get_class($lawan ?? new \stdClass), + 'nama' => $lawan->nama_lengkap ?? 'User Terhapus', + 'foto' => $lawan->foto ?? null, + 'last_message' => $lastMsg->isi_pesan, + 'time' => $lastMsg->created_at->diffForHumans(), + 'unread' => $msgs->where('penerima_id', $user->id)->where('sudah_dibaca', false)->count() + ]; + }); + + $view = $isPetani ? 'petani.pesan.index' : 'landing.pesan.index'; + return view($view, compact('chatList')); + } + + // Menampilkan Detail Chat + public function show($id) + { + $user = $this->getAuthenticatedUser(); + $isPetani = Auth::guard('petani')->check(); + + // Tentukan model lawan bicara + $lawanType = $isPetani ? Pembeli::class : Petani::class; + $lawan = $lawanType::findOrFail($id); + + // Ambil percakapan antara User Login & Lawan Bicara + $chats = Pesan::where(function ($q) use ($user, $lawan, $lawanType) { + $q->where('pengirim_id', $user->id)->where('pengirim_type', get_class($user)) + ->where('penerima_id', $lawan->id)->where('penerima_type', $lawanType); + })->orWhere(function ($q) use ($user, $lawan, $lawanType) { + $q->where('pengirim_id', $lawan->id)->where('pengirim_type', $lawanType) + ->where('penerima_id', $user->id)->where('penerima_type', get_class($user)); + })->orderBy('created_at', 'asc')->get(); + + // Tandai pesan masuk sebagai "Sudah Dibaca" + Pesan::where('pengirim_id', $lawan->id)->where('pengirim_type', $lawanType) + ->where('penerima_id', $user->id)->update(['sudah_dibaca' => true]); + + $view = $isPetani ? 'petani.pesan.show' : 'landing.pesan.show'; + return view($view, compact('chats', 'lawan')); + } + + // Proses Kirim Pesan + public function store(Request $request) + { + $request->validate(['isi_pesan' => 'required']); + $user = $this->getAuthenticatedUser(); + $isPetani = Auth::guard('petani')->check(); + + // Menentukan tipe penerima + $penerimaType = $isPetani ? 'App\Models\Pembeli' : 'App\Models\Petani'; + + Pesan::create([ + 'pengirim_id' => $user->id, + 'pengirim_type' => get_class($user), + 'penerima_id' => $request->penerima_id, + 'penerima_type' => $penerimaType, + 'isi_pesan' => $request->isi_pesan, + 'sudah_dibaca' => false, + ]); + + return back(); + } + + private function getAuthenticatedUser() + { + if (Auth::guard('petani')->check()) return Auth::guard('petani')->user(); + if (Auth::guard('pembeli')->check()) return Auth::guard('pembeli')->user(); + abort(403); + } +} diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index ba148d1..fa1084e 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -113,7 +113,7 @@ public function prosesCheckout(Request $request) $subtotal_transaksi = 0; $kode_invoice = 'INV/' . date('Ymd') . '/' . rand(1000, 9999); - // Buat Header Transaksi dulu + // Membuat Header Transaksi $transaksi = Transaksi::create([ 'pembeli_id' => $pembeli_id, 'tanggal_transaksi' => now(), @@ -144,7 +144,6 @@ public function prosesCheckout(Request $request) $transaksi->update(['total_harga' => $subtotal_transaksi]); } - // Hapus Keranjang setelah sukses session()->forget('cart'); } }); @@ -223,7 +222,7 @@ public function pesananDetail($id) { $petaniId = Auth::guard('petani')->id(); - // Ambil transaksi berdasarkan ID, pastikan transaksi tersebut memiliki produk milik petani ini + // Ambil transaksi berdasarkan ID $pesanan = Transaksi::whereHas('details.produk', function ($q) use ($petaniId) { $q->where('petani_id', $petaniId); }) diff --git a/app/Models/Pembeli.php b/app/Models/Pembeli.php index 8d33586..1ef0942 100644 --- a/app/Models/Pembeli.php +++ b/app/Models/Pembeli.php @@ -27,4 +27,14 @@ public function transaksis() { return $this->hasMany(Transaksi::class, 'pembeli_id'); } + + public function pesanMasuk() + { + return $this->morphMany(Pesan::class, 'penerima'); + } + + public function pesanTerkirim() + { + return $this->morphMany(Pesan::class, 'pengirim'); + } } \ No newline at end of file diff --git a/app/Models/Pesan.php b/app/Models/Pesan.php index 464d07c..adcfcc2 100644 --- a/app/Models/Pesan.php +++ b/app/Models/Pesan.php @@ -4,6 +4,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\MorphTo; class Pesan extends Model { @@ -19,5 +20,15 @@ class Pesan extends Model 'isi_pesan', 'sudah_dibaca' ]; + + public function pengirim(): MorphTo + { + return $this->morphTo(); + } + + public function penerima(): MorphTo + { + return $this->morphTo(); + } } \ No newline at end of file diff --git a/app/Models/Petani.php b/app/Models/Petani.php index 88ebbfd..f1b3b64 100644 --- a/app/Models/Petani.php +++ b/app/Models/Petani.php @@ -2,7 +2,7 @@ namespace App\Models; -use Illuminate\Foundation\Auth\User as Authenticatable; // PENTING: Ganti ini +use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class Petani extends Authenticatable @@ -29,4 +29,14 @@ public function produks() { return $this->hasMany(Produk::class, 'petani_id'); } + + public function pesanMasuk() + { + return $this->morphMany(Pesan::class, 'penerima'); + } + + public function pesanTerkirim() + { + return $this->morphMany(Pesan::class, 'pengirim'); + } } \ No newline at end of file diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index a4fc992..5ecc482 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -16,7 +16,7 @@ -

Log in.

+

Log in

{{-- Pesan Sukses Register --}} @if (session('success')) @@ -37,16 +37,16 @@
@csrf
- +
- +
- +
-
+

Belum punya akun? Daftar.

diff --git a/resources/views/landing/detail.blade.php b/resources/views/landing/detail.blade.php index 8c3af34..fae9d48 100644 --- a/resources/views/landing/detail.blade.php +++ b/resources/views/landing/detail.blade.php @@ -64,12 +64,46 @@ class="form-control form-control-sm text-center border-0" value="1" - + Beli Sekarang + + +
-