Setelah berhasil membuat component untuk menu customer, maka kita akan lanjutkan belajar membuat component livewire untuk menampilkan data my orders / transaksi berdasarkan customer yang sedang login.
Langkah 1 - Membuat Component My Orders
Silahkan teman-teman jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel-nya.
go
php artisan make:livewire Account/MyOrders/Index
Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 2 file baru, yaitu:
- Class Component:
app/Livewire/Account/MyOrders/Index.php - View Component:
resources/views/livewire/account/my-orders/index.blade.php
Langkah 2 - Membuat Route My Orders Index
Sekarang kita akan lanjutkan membuat route yang nanti digunakan untuk menampilkan halaman my orders.
Silahkan buka file routes/web.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.
php
<?php
namespace App\Livewire;
use Illuminate\Support\Facades\Route;
//route register
Route::get('/register', Auth\Register::class)->name('register');
//route login
Route::get('/login', Auth\Login::class)->name('login');
//route group account
Route::middleware('auth:customer')->group(function () {
Route::group(['prefix' => 'account'], function () {
//route my order
Route::get('/my-orders', Account\MyOrders\Index::class)->name('account.my-orders.index');
});
});
Dari perubahan kode di atas, kita membuat 2 route group, yaitu:
-
middleware
auth:customer- artinya semua route yang dibuat di dalamnya hanya bisa diakses jika sudah melakukan proses login.phpRoute::middleware('auth:customer')->group(function () { //... } -
prefix
account- artinya semua route yang dibuat di dalamnya akan ditambahkan awalan/accountpada URL-nya.phpRoute::group(['prefix' => 'account'], function () { //... }
Di dalam kedua route group di atas kita membuat route baru untuk halaman my-orders.
css
Route::get('/my-orders', Account\MyOrders\Index::class)->name('account.my-orders.index');
Langkah 3 - Get Data Transaksi di Class Component
Selanjutnya adalah belajar bagaimana mengambil data transaksi berdasarkan customer yang login di dalam class component.
Silahkan teman-teman buka file app/Livewire/Account/MyOrders/Index.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.
php
<?php
namespace App\Livewire\Account\MyOrders;
use Livewire\Component;
use App\Models\Transaction;
class Index extends Component
{
public function render()
{
//get transactions
$transactions = Transaction::query()
->where('customer_id', auth()->guard('customer')->user()->id)
->latest()
->simplePaginate(3);
return view('livewire.account.my-orders.index', compact('transactions'));
}
}
Dari perubahan kode di atas, pertama kita import Model Transaction.
perl
use App\Models\Transaction;
Kemudian di dalam method render kita membuat variable $transactions dan berisi get data ke Model Transaction berdasarkan customer_id yang sedang login.
php
//get transactions
$transactions = Transaction::query()
->where('customer_id', auth()->guard('customer')->user()->id)
->latest()
->simplePaginate(3);
Kemudian kita kirimkan data di atas ke dalam view component menggunakan compact.
kotlin
return view('livewire.account.my-orders.index', compact('transactions'));
Langkah 4 - Menampilkan Data My Orders / Transactions
Silahkan teman-teman buka file resources/views/livewire/account/my-orders/index.blade.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.
javascript
<div class="container">
<div class="row justify-content-center mt-0" style="margin-bottom: 150px;">
<div class="col-md-6">
<x-menus.customer />
<div class="card border-0 shadow-sm rounded">
<div class="card-body p-4">
<h6>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" class="bi bi-bag mb-1" viewBox="0 0 16 16">
<path d="M8 1a2.5 2.5 0 0 1 2.5 2.5V4h-5v-.5A2.5 2.5 0 0 1 8 1m3.5 3v-.5a3.5 3.5 0 1 0-7 0V4H1v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4zM2 5h12v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z" />
</svg>
My Orders
</h6>
<hr />
@forelse ($transactions as $transaction)
<div class="card rounded border mb-3">
<div class="row g-0">
<div class="col-12 col-md-12">
<a href="{{ route('account.my-orders.show', $transaction->snap_token) }}" wire:navigate class="text-decoration-none text-dark">
<div class="card-body">
<div class="d-flex justify-content-between">
<div class="mt-2">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-basket3 mb-1 me-2" viewBox="0 0 16 16">
<path d="M5.757 1.071a.5.5 0 0 1 .172.686L3.383 6h9.234L10.07 1.757a.5.5 0 1 1 .858-.514L13.783 6H15.5a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H.5a.5.5 0 0 1-.5-.5v-1A.5.5 0 0 1 .5 6h1.717L5.07 1.243a.5.5 0 0 1 .686-.172zM3.394 15l-1.48-6h-.97l1.525 6.426a.75.75 0 0 0 .729.574h9.606a.75.75 0 0 0 .73-.574L15.056 9h-.972l-1.479 6z" />
</svg>
<span class="fw-bold">Order ID #{{ $transaction->invoice }}</span>
</div>
<div>
@if($transaction->status == 'pending')
<button class="btn btn-warning btn-sm rounded shadow-sm border-0">PENDING</button>
@elseif($transaction->status == 'success')
<button class="btn btn-success btn-sm rounded shadow-sm border-0">SUCCESS</button>
@elseif($transaction->status == 'expired')
<button class="btn btn-warning btn-sm rounded shadow-sm border-0" disabled>EXPIRED</button>
@elseif($transaction->status == 'failed')
<button class="btn btn-danger btn-sm rounded shadow-sm border-0">FAILED</button>
@endif
</div>
</div>
<hr>
<div class="d-flex justify-content-between">
<div>
<span class="fw-bold">Grand Total:</span>
</div>
<div>
<span class="fw-bold">Rp. {{ number_format($transaction->total) }}</span>
</div>
</div>
</div>
</a>
</div>
</div>
</div>
@empty
<div class="card rounded border mb-3">
<div class="card-body">
<div class="d-flex justify-content-center">
<div class="mt-2">
<span class="fw-bold">You don't have any orders.</span>
</div>
</div>
</div>
</div>
@endforelse
<!-- Navigasi Pagination -->
{{ $transactions->links('vendor.pagination.simple-default') }}
</div>
</div>
</div>
</div>
</div>
Dari penambahan kode di atas, pertama kita panggil component menu customer.
xml
<x-menus.customer />
Kemudian untuk menampilkan data, kita menggunakan directive @forelse.
less
@forelse ($transactions as $transaction)
//data orders
@empty
//tidak ada data orders
@endforelse
Dan untuk menampilkan pagination, kita bisa menggunakan sintaks seperti berikut ini.
php
{{ $transactions->links('vendor.pagination.simple-default') }}
Jika teman-teman perhatikan, di atas pada view pagination kita arahkan ke vendor/pagination/simple-default. Sedangkan view tersebut untuk saat ini belum ada, maka kita akan publish dulu file tersebut pada langkah berikutnya.
Langkah 5 - Publish View Pagination
Di atas, karena kita akan melakukan custom view pagination, maka kita akan publish dulu view dari pagination Laravel.
Silahkan teman-teman jalankan perintah berikut ini.
lua
php artisan vendor:publish --tag=laravel-pagination
Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan beberapa view untuk pagination dari Laravel, yang berada di dalam folder berikut ini.
bashresources/views/vendor/pagination/*
Langkah 6 - Custom Pagination Laravel
Sekarang kita akan lakukan custom pagination bawaan dari Laravel agar sesuai dengan yang kita inginkan dan namanya adalah simple-default.
Silahkan teman-teman buka file resources/views/vendor/pagination/simple-default.blade.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.
scss
@if ($paginator->hasPages())
<div class="d-flex justify-content-between mt-2">
{{-- Tombol Previous --}}
@if ($paginator->onFirstPage())
<button class="btn btn-orange-2 rounded shadow-sm border-0" disabled>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrow-left mb-1" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8" />
</svg>
Previous
</button>
@else
<a href="{{ $paginator->previousPageUrl() }}" class="btn btn-orange-2 rounded shadow-sm border-0" wire:navigate>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrow-left mb-1" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8" />
</svg>
Previous
</a>
@endif
{{-- Tombol Next --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" class="btn btn-orange-2 rounded shadow-sm border-0" wire:navigate>
Next
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrow-right mb-1" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8" />
</svg>
</a>
@else
<button class="btn btn-orange-2 rounded shadow-sm border-0" disabled>
Next
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrow-right mb-1" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8" />
</svg>
</button>
@endif
</div>
@endif
Langkah 7 - Uji Coba Menampilkan Halaman My Orders
Silahkan teman-teman login dan jika berhasil maka akan diarahkan pada halaman My Orders, kurang lebih seperti berikut ini.
