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:

order administrator

Kemudian jika view diklik, akan memanggil fungsi show dan menghasilkan output seperti berikut:

order detail

Lakukan update status order jika ingin merubah status order. Misal order Id 18 kita update jadi completed.

order completed

Selesaaii!!! Selamat Mencoba!!! Silahkan tinggalkan komentar jika ada yang perlu didiskusikan.