Melanjutkan tutorial sebelumnya tentang order integrasi midtrans dalam pembayaran, kali ini kita akan buat tutorial menampilkan halaman order di administrator dan merubah status nya.
Langkah 1. Controller AdminOrder
Buat Controller dengan nama AdminOrderController dengan perintah:
php artisan make:controller AdminOrderController
Isi file tersebut dengan code berikut:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\OrderItem;
use Illuminate\Http\Request;
use Inertia\Inertia;
class AdminOrderController extends Controller
{
public function index()
{
$orders = Order::with('user', 'items.product')->latest()->paginate(8);
return Inertia::render('Orders/Index', [
'orders' => $orders,
]);
}
public function show(Order $order)
{
$order->load('items.product', 'user');
return Inertia::render('Orders/Show', [
'order' => $order,
]);
}
public function updateStatus(Request $request, Order $order)
{
$request->validate([
'status' => 'required|string|in:pending,paid,shipped,completed,canceled',
]);
$order->update(['status' => $request->status]);
return redirect()->route('admin.orders.index')->with('success', 'Order status updated successfully.');
}
}
Langkah 2. Buat file vue.
Buat file di path resources/js/Pages/Orders/Index.vue
dan isi code berikut:
<template>
<div class="flex min-h-screen bg-gray-100">
<!-- Sidebar -->
<aside class="w-64 bg-blue-600 text-white flex-shrink-0">
<div class="p-6">
<h2 class="text-2xl font-bold">Admin Panel</h2>
</div>
<nav class="mt-6">
<ul>
<li>
<Link href="/dashboard"
class="block px-4 py-2 hover:bg-blue-700"
>
Dashboard
</Link>
</li>
<li>
<Link href="/categories"
class="block px-4 py-2 hover:bg-blue-700"
>
Categories
</Link>
</li>
<li>
<Link href="/products"
class="block px-4 py-2 hover:bg-blue-700"
>
Products
</Link>
</li>
<li>
<Link href="/admin/orders"
class="block px-4 py-2 hover:bg-blue-700"
>
Orders
</Link>
</li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 p-6">
<h1 class="text-2xl font-bold mb-4">Orders</h1>
<table class="min-w-full bg-white">
<thead>
<tr>
<th class="px-6 py-3 border-b">Order ID</th>
<th class="px-6 py-3 border-b">Customer</th>
<th class="px-6 py-3 border-b">Total</th>
<th class="px-6 py-3 border-b">Status</th>
<th class="px-6 py-3 border-b">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="order in orders.data" :key="order.id">
<td class="px-6 py-4 border-b">{{ order.id }}</td>
<td class="px-6 py-4 border-b">{{ order.user.name }}</td>
<td class="px-6 py-4 border-b">Rp {{ order.total_price }}</td>
<td class="px-6 py-4 border-b">{{ order.status }}</td>
<td class="px-6 py-4 border-b">
<Link :href="route('admin.orders.show', order.id)" class="text-blue-500">View</Link>
</td>
</tr>
</tbody>
</table>
<Pagination :links="orders.links" />
</main>
</div>
</template>
<script>
import { Link, usePage } from '@inertiajs/vue3';
import Pagination from '@/Components/Pagination.vue';
export default {
components: { Link, Pagination },
props: {
orders: Object,
},
};
</script>
Buat file Show.vue di
resources/js/Pages/Orders/Show.vue Lalu isi dengan code berikut:
// resources/js/Pages/Admin/Orders/Show.vue
<template>
<div class="flex min-h-screen bg-gray-100">
<!-- Sidebar -->
<aside class="w-64 bg-blue-600 text-white flex-shrink-0">
<div class="p-6">
<h2 class="text-2xl font-bold">Admin Panel</h2>
</div>
<nav class="mt-6">
<ul>
<li>
<Link href="/dashboard"
class="block px-4 py-2 hover:bg-blue-700"
>
Dashboard
</Link>
</li>
<li>
<Link href="/categories"
class="block px-4 py-2 hover:bg-blue-700"
>
Categories
</Link>
</li>
<li>
<Link href="/products"
class="block px-4 py-2 hover:bg-blue-700"
>
Products
</Link>
</li>
<li>
<Link href="/admin/orders"
class="block px-4 py-2 hover:bg-blue-700"
>
Orders
</Link>
</li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 p-6">
<h1 class="text-2xl font-bold mb-4">Order Details</h1>
<p><strong>Order ID:</strong> {{ order.id }}</p>
<p><strong>Customer:</strong> {{ order.user.name }}</p>
<p><strong>Status:</strong> {{ order.status }}</p>
<table class="min-w-full bg-white mt-4">
<thead>
<tr>
<th class="px-6 py-3 border-b">Product</th>
<th class="px-6 py-3 border-b">Quantity</th>
<th class="px-6 py-3 border-b">Price</th>
</tr>
</thead>
<tbody>
<tr v-for="item in order.items" :key="item.id">
<td class="px-6 py-4 border-b">{{ item.product.name }}</td>
<td class="px-6 py-4 border-b">{{ item.quantity }}</td>
<td class="px-6 py-4 border-b">${{ item.price }}</td>
</tr>
</tbody>
</table>
<form @submit.prevent="updateStatus" class="mt-4">
<label for="status" class="block text-sm font-medium text-gray-700">Update Status</label>
<select v-model="form.status" id="status" class="block w-full mt-1">
<option value="pending">Pending</option>
<option value="paid">Paid</option>
<option value="shipped">Shipped</option>
<option value="completed">Completed</option>
<option value="canceled">Canceled</option>
</select>
<button type="submit" class="mt-2 px-4 py-2 bg-blue-500 text-white">Update</button>
</form>
</main>
</div>
</template>
<script>
import { Link, usePage } from '@inertiajs/vue3';
import { useForm } from '@inertiajs/vue3';
export default {
components: { Link},
props: {
order: Object,
},
setup(props) {
const form = useForm({
status: props.order.status,
});
const updateStatus = () => {
form.put(route('admin.orders.updateStatus', props.order.id));
};
return { form, updateStatus };
},
};
</script>
Langkah 3. Route
Buka file web.php dan tambahkan route berikut:
use App\Http\Controllers\AdminOrderController;
Route::middleware(['auth', 'verified'])->prefix('admin')->group(function () {
Route::get('/orders', [AdminOrderController::class, 'index'])->name('admin.orders.index');
Route::get('/orders/{order}', [AdminOrderController::class, 'show'])->name('admin.orders.show');
Route::put('/orders/{order}/update-status', [AdminOrderController::class, 'updateStatus'])->name('admin.orders.updateStatus');
});
Langkah 4. Update relasi Model Order, OrderItem dan Product
Buka model Order.php dan edit code menjadi berikut:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $fillable = ['user_id', 'total_price', 'status'];
public function items()
{
return $this->hasMany(OrderItem::class);
}
// Relasi ke model User
public function user()
{
return $this->belongsTo(User::class);
}
}
Kita menambahkan fungsi user, untuk melakukan relasi user ke order.
Kemudian edit file OrderItem.php menjadi sebagai berikut:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OrderItem extends Model
{
protected $fillable = ['order_id', 'product_id', 'quantity', 'price'];
public function order()
{
return $this->belongsTo(Order::class);
}
// Relasi ke model Product
public function product()
{
return $this->belongsTo(Product::class);
}
}
Dan model Product.php menjadi sebagai berikut:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'slug',
'price',
'stock',
'description',
'category_id'
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function images()
{
return $this->hasMany(ProductImage::class);
}
public function orderItems()
{
return $this->hasMany(OrderItem::class);
}
}
Kita menambahkan function Orderitems agar product bisa memiliki banyak item yang diorder.
Langkah 5. Buat File Komponen Pagination
Buat file Pagination.vue di direktori resources/js/Components/:
<template>
<div v-if="links.length > 1" class="flex items-center justify-center mt-4">
<nav>
<ul class="flex items-center space-x-2">
<li
v-for="(link, index) in links"
:key="index"
:class="{ 'font-bold': link.active }"
>
<a
v-if="link.url"
:href="link.url"
class="px-3 py-1 border rounded text-sm"
:class="{
'bg-blue-500 text-white': link.active,
'hover:bg-gray-200': !link.active,
}"
v-html="link.label"
></a>
<span v-else v-html="link.label" class="px-3 py-1 text-sm text-gray-500"></span>
</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
props: {
links: {
type: Array,
required: true,
},
},
};
</script>
<style scoped>
/* Tambahkan styling jika diperlukan */
</style>
File ini digunakan untuk pagination tabel di halaman order administrator.
Langkah 6. Testing.
Lakukan testing dengan akses URL administrator:
http://localhost:8000/admin/orders
Jika berhasil, akan menghasilkan output berikut:
Kemudian jika view diklik, akan memanggil fungsi show dan menghasilkan output seperti berikut:
Lakukan update status order jika ingin merubah status order. Misal order Id 18 kita update jadi completed.
Selesaaii!!! Selamat Mencoba!!! Silahkan tinggalkan komentar jika ada yang perlu didiskusikan.