Tutorial Laravel 12 API Next JS 15 dan Tailwind CSS #15 Product Table

Belajar membangun aplikasi fullstack modern dengan backend Laravel 12 RESTful API, frontend Next.js, dan desain menggunakan Tailwind CSS. Tutorial ini membahas step-by-step mulai dari setup environment, pembuatan API, konsumsi API di Next.js, hingga integrasi UI responsif.

✅ Telah dilihat 216 kali

Rating: 5.00 ⭐

... 13 August 2025, 20:33

Konfigurasi Product Table

Silakan teman-teman buka file ProductTable.tsx kemudian sesuaikan menjadi seperti berikut ini:

components/
├── products/
    ├── Breadcrumbs.tsx
    ├── DeleteConfirmDialog.tsx
    ├── ProductForm.tsx
    ├── ProductTable.tsx <-----

Kode Lengkap

"use client"

import { Button } from "@/components/ui/button"
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Product } from "@/services/products"

export function ProductTable({
  products,
  onEdit,
  onDelete,
}: {
  products: Product[]
  onEdit: (product: Product) => void
  onDelete: (product: Product) => void
}) {
  if (products.length === 0) {
    return <p className="text-center text-gray-500">Tidak ada produk tersedia</p>
  }

  return (
    <Table>
      <TableCaption>List of available products</TableCaption>
      <TableHeader>
        <TableRow>
          <TableHead className="w-[50px]">ID</TableHead>
          <TableHead>Name</TableHead>
          <TableHead className="text-right">Price</TableHead>
          <TableHead className="text-right">Stock</TableHead>
          <TableHead className="text-center">Actions</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {products.map((product) => (
          <TableRow key={product.id}>
            <TableCell>{product.id}</TableCell>
            <TableCell className="font-medium">{product.name}</TableCell>
            <TableCell className="text-right">
              {product.price.toLocaleString("id-ID", { style: "currency", currency: "IDR" })}
            </TableCell>
            <TableCell className={`text-right ${product.stock < 10 ? "text-red-600 font-bold" : ""}`}>
              {product.stock}
            </TableCell>
            <TableCell className="text-center space-x-2">
              <Button variant="outline" onClick={() => onEdit(product)}>
                Edit
              </Button>
              <Button variant="destructive" onClick={() => onDelete(product)}>
                Delete
              </Button>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

use client

"use client"
  • Menandakan bahwa ProductTable adalah Client Component.
  • Kenapa? Karena tabel ini memiliki event handler (onEditonDelete) yang hanya bisa dijalankan di sisi browser.
  • Tanpa use client, tombol Edit dan Delete tidak akan bisa berfungsi.

Import

import { Button } from "@/components/ui/button"
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Product } from "@/services/products"
  • Button → tombol dari shadcn/ui untuk aksi edit dan delete.
  • TableTableHeaderTableRowTableCell, dll. → komponen table dari shadcn/ui untuk membuat tabel yang rapi dan konsisten.
  • Product → tipe data produk (biasanya { id, name, price, stock }) dari services/products.

Props Komponen

Komponen ProductTable menerima props berikut:

  • products: Product[] → daftar produk yang akan ditampilkan di tabel.
  • onEdit: (product: Product) => void → callback ketika user klik tombol Edit.
  • onDelete: (product: Product) => void → callback ketika user klik tombol Delete.

Struktur Tabel

<Table>
  <TableCaption>List of available products</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead className="w-[50px]">ID</TableHead>
      <TableHead>Name</TableHead>
      <TableHead className="text-right">Price</TableHead>
      <TableHead className="text-right">Stock</TableHead>
      <TableHead className="text-center">Actions</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    {products.map((product) => (
      <TableRow key={product.id}>
        <TableCell>{product.id}</TableCell>
        <TableCell className="font-medium">{product.name}</TableCell>
        <TableCell className="text-right">
          {product.price.toLocaleString("id-ID", { style: "currency", currency: "IDR" })}
        </TableCell>
        <TableCell className={`text-right ${product.stock < 10 ? "text-red-600 font-bold" : ""}`}>
          {product.stock}
        </TableCell>
        <TableCell className="text-center space-x-2">
          <Button variant="outline" onClick={() => onEdit(product)}>Edit</Button>
          <Button variant="destructive" onClick={() => onDelete(product)}>Delete</Button>
        </TableCell>
      </TableRow>
    ))}
  </TableBody>
</Table>

Detail:

  • TableCaption → teks deskriptif di bawah tabel (List of available products).
  • TableHeader → baris judul kolom (IDNamePriceStockActions).
  • TableBody → menampilkan baris data produk dengan map().
  • Harga (price) → diformat dengan toLocaleString("id-ID", { style: "currency", currency: "IDR" }) agar tampil dalam format Rupiah.
  • Stok (stock) → jika stok kurang dari 10, tampil dengan teks merah tebal sebagai peringatan.
  • Actions → ada dua tombol:
    • Edit → variant outline, memanggil onEdit(product).
    • Delete → variant destructive, memanggil onDelete(product).

Fallback Ketika Data Kosong

if (products.length === 0) {
  return <p className="text-center text-gray-500">Tidak ada produk tersedia</p>
}
  • Jika daftar produk kosong, tampilkan teks "Tidak ada produk tersedia" di tengah layar.

Kesimpulan

ProductTable.tsx adalah komponen tabel untuk menampilkan daftar produk lengkap dengan:

  1. Kolom ID, Nama, Harga (Rupiah), Stok, dan Aksi.
  2. Indikator stok rendah (warna merah).
  3. Tombol aksi Edit dan Delete.
  4. Pesan fallback kalau data kosong.

🔥 Flash Sale


📜 Table Of Contents


📌 Daftar Episode


Daftar eBook