My Course — Membangun Website Food Store Dengan Laravel Filament, Livewire dan Payment Gateway

Membuat Component Cart Index


Pada materi kali ini kita semua akan belajar bagaimana cara membuat component livewire untuk menampilkan data cart.

Langkah 1 - Membuat Component Cart Index

Silahkan teman-teman jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel-nya.

go
php artisan make:livewire Web/Cart/Index

Jika perintah di atas berhasil dijalankan, maka kita akan mendapatkan 2 file baru, yaitu:

  1. Class Component: app/Livewire/Web/Cart/Index.php
  2. View Component: resources/views/livewire/web/cart/index.blade.php

Langkah 2 - Membuat Route Cart

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'); //route my order show Route::get('/my-orders/{snap_token}', Account\MyOrders\Show::class)->name('account.my-orders.show'); //route my profile Route::get('/my-profile', Account\MyProfile\Index::class)->name('account.my-profile'); //route password Route::get('/password', Account\Password\Index::class)->name('account.password'); }); }); //route home Route::get('/', Web\Home\Index::class)->name('home'); //route products index Route::get('/products', Web\Products\Index::class)->name('web.product.index'); //route category show Route::get('/category/{slug}', Web\Category\Show::class)->name('web.category.show'); //route product show Route::get('/products/{slug}', Web\Products\Show::class)->name('web.product.show'); //route cart Route::get('/cart', Web\Cart\Index::class)->name('web.cart.index')->middleware('auth:customer');

Dari perubahan kode di atas, kita menambahkan route baru untuk halaman cart index dengan memberikan path URL /cart. Dan kita tambahkan middleware auth:customer, artinya route ini hanya bisa diakses jika customer sudah login.

css
Route::get('/cart', Web\Cart\Index::class)->name('web.cart.index')->middleware('auth:customer');

Langkah 3 - Get Data Cart di Class Component

Sekarang kita akan melakukan get data carts pada class component, kemudian nanti akan kita kirimkan ke view component untuk ditampilkan.

Silahkan teman-teman buke file app/Livewire/Web/Cart/Index.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.

php
<?php namespace App\Livewire\Web\Cart; use App\Models\Cart; use Livewire\Component; class Index extends Component { public function render() { //get carts by customer $carts = Cart::query() ->with('product') ->where('customer_id', auth()->guard('customer')->user()->id) ->latest() ->get(); // Menghitung total berat $totalWeight = $carts->sum(function ($cart) { return $cart->product->weight * $cart->qty; }); // Menghitung total harga $totalPrice = $carts->sum(function ($cart) { return $cart->product->price * $cart->qty; }); return view('livewire.web.cart.index', compact('carts', 'totalWeight', 'totalPrice')); } }

Dari perubahan kode di atas, pertama kita import Model Cart.

perl
use App\Models\Cart;

Kemudian di dalam method render kita melakukan get data carts dari database menggunakan Model berdasarkan customer yang login.

php
//get carts by customer $carts = Cart::query() ->with('product') ->where('customer_id', auth()->guard('customer')->user()->id) ->latest() ->get();

Kemudian kita menghitung total berat (weight) dan total harga yang ada pada data carts.

php
// Menghitung total berat $totalWeight = $carts->sum(function ($cart) { return $cart->product->weight * $cart->qty; }); // Menghitung total harga $totalPrice = $carts->sum(function ($cart) { return $cart->product->price * $cart->qty; });

Setelah itu, kita kirimkan ketiga data di atas ke dalam view component menggunakan method compaact.

kotlin
return view('livewire.web.cart.index', compact('carts', 'totalWeight', 'totalPrice'));

Langkah 4 - Menampilkan Data Carts

Sekarang kita akan belajar menampilkan data-nya menggunakan perulangan @foreach. Silahkan teman-teman buka file resources/views/livewire/web/cart/index.blade.php, kemudian ubah semua kode-nya menjadi seperti berikut ini.

xml
@section('title') Carts - Eat Your Favorite Foods @stop @section('keywords') Food Store, Eat Your Favorite Foods @stop @section('description') Food Store - Eat Your Favorite Foods @stop @section('image') {{ asset('images/logo.png') }} @stop <div> <div class="container"> <div class="row justify-content-center mt-0" style="margin-bottom: 270px;"> <div class="col-md-6"> <div class="bg-white rounded-bottom-custom shadow-sm p-3 sticky-top mb-5"> <div class="d-flex justify-content-start"> <div> <x-buttons.back /> </div> </div> </div> <div class="row"> @forelse ($carts as $cart) <div class="col-12 col-md-12 mb-4"> <div class="card rounded border-0 shadow-sm"> <div class="row g-0"> <div class="col-5 col-md-4"> <img src="{{ asset('/storage/' . $cart->product->image) }}" class="img-fluid w-100 h-100 object-fit-cover rounded-start"> </div> <div class="col-7 col-md-8"> <div class="card-body"> <div class="d-flex justify-content-between mt-4"> <div class="text-start"> <h6 class="card-title">{{ $cart->product->title }}</h6> </div> <div class="text-end"> <!-- btn delete --> </div> </div> <div class="d-flex justify-content-between mt-4"> <div class="text-start"> <span class="text-success fw-bold">Rp. {{ number_format($cart->product->price) }}</span> </div> <div class="text-end"> <div class="input-group justify-content-center align-items-center group-btn-qty"> <!-- qty cart --> <input type="number" step="1" max="10" value="{{ $cart->qty }}" name="quantity" class="quantity-field border-0 text-center w-25" style="background: transparent;"> </div> </div> </div> </div> </div> </div> </div> </div> @empty <div class="col-12 col-md-12 mb-4"> <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 items in the cart.</span> </div> </div> </div> </div> </div> @endforelse </div> </div> </div> </div> @if(count($carts) > 0) <div class="container fixed-total"> <div class="row justify-content-center"> <div class="col-12 col-md-6"> <div class="card rounded shadow-sm border-0 mb-5 "> <div class="card-body"> <div class="d-flex justify-content-between"> <div> <h6 class="fw-bold mb-0">Total</h6> </div> <div class="ms-auto"> <h6 class="fw-bold mb-0">Rp. {{ number_format($totalPrice) }}</h6> </div> </div> <hr style="border: dotted 1px #e92715;"> <a href="/checkout" wire:navigate class="btn btn-orange-2 rounded border-0 shadow-sm w-100">Process to Checkout</a> </div> </div> </div> </div> </div> @endif </div>

Dari penambahan kode di atas, kita menampilkan data-nya dengan cara me-looping (perulangan) menggunakan directive @forelse.

less
@forelse ($carts as $cart) //data cart @empty //tidak ada data cart @endforelse

Langkah 5 - Uji Coba Menampilkan Cart Index

Silahkan teman-teman buka link berikut ini http://localhost:8000/cart, jika berhasil maka kurang lebih hasilnya seperti berikut ini.