Inventaris Lab Laravel 12 : Bagian #09 - MEMBUAT HALAMAN TRANSAKSI PEMINJAMAN (LOAN)
Belajar Bareng Minarsih - Edisi Ngoding
10 Oktober 2025
Tujuan: Di bagian ini, kita akan membuat fitur untuk mencatat dan mengelola data transaksi peminjaman barang. Kita akan belajar lebih dalam tentang cara menampilkan data dari beberapa tabel yang saling berhubungan (relationships) dalam satu tampilan. Di akhir, kita akan menambahkan fitur khusus untuk proses pengembalian barang.
Seperti biasa, kita siapkan "jalan" (Route) dan "otak" (Controller) terlebih dahulu.
use App\Http\Controllers\LoanController;
Route::middleware('auth')->group(function () {
// ... route dashboard, users, category, item
Route::resource('loan', LoanController::class);
});
php artisan route:list --name=loan
Sekarang, kita isi logika pada controller untuk mengambil data peminjaman dari database.
use App\Models\Loan;
class LoanController extends Controller
{
// Variabel untuk data umum
protected $title = 'Peminjaman';
protected $menu = 'loan';
protected $directory = 'admin.loan'; // Diubah ke folder view loan
public function index()
{
// Menyiapkan array untuk dikirim ke view
$data['title'] = $this->title;
$data['menu'] = $this->menu;
// Mengambil data dari database
$data['loans'] = Loan::with(['user', 'item'])->latest()->get();
// Me-return view beserta data
return view($this->directory . '.index', $data);
}
Penjelasan Kode: Perintah .with(['user', 'item']) adalah Eager Loading untuk banyak relasi sekaligus. Ini berarti: "Ambil semua data peminjaman, dan untuk setiap peminjaman, sertakan juga data user (peminjam) dan data item (barang yang dipinjam)".
Kita akan kembali menggunakan metode duplikasi.
Kita akan mengubah file index.blade.php untuk menampilkan ringkasan data peminjaman.
@extends('admin.layouts.app')
@section('css')
{{-- CSS Tambahan --}}
@endsection
@section('content')
<div class="card">
<div class="card-body">
<h5 class="card-title fw-semibold mb-4">Data {{ $title }}</h5>
<a href="{{ route('loan.create') }}" class="btn btn-primary mb-4">Tambah Data {{ $title }}</a>
<div class="table-responsive">
<table id="datatable" class="table table-striped">
<thead>
<tr>
<th>No</th>
<th>Nama Peminjam</th>
<th>Nama Barang</th>
<th>Tanggal Pinjam</th>
<th>Status</th>
<th>Aksi</th>
</tr>
</thead>
<tbody>
@foreach ($loans as $loan)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $loan->user->name }}</td>
<td>
<small>{{ $loan->item->unique_code }}</small><br>
<span class="fw-bold">{{ $loan->item->name }}</span>
</td>
<td>{{ \Carbon\Carbon::parse($loan->loan_date)->format('d-m-Y') }}</td>
<td>
@if ($loan->status == 'Dipinjam')
<span class="badge bg-warning">{{ $loan->status }}</span>
@else
<span class="badge bg-success">{{ $loan->status }}</span>
@endif
</td>
<td>
<a href="{{ route('loan.edit', $loan->id) }}" class="btn btn-warning btn-sm">Ubah</a>
<form id="deleteForm{{ $loan->id }}"
action="{{ route('loan.destroy', $loan->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="button" class="btn btn-danger btn-sm"
onclick="confirmDelete({{ $loan->id }})">Hapus</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection
@section('js')
<script>
$(document).ready(function() {
$('#datatable').DataTable();
});
// Script untuk SweetAlert
function confirmDelete(id) {
swal({
title: "Apakah anda yakin?",
text: "Data yang dihapus tidak dapat dikembalikan!",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
// Jika pengguna menekan "OK", submit form
$('#deleteForm' + id).submit();
} else {
// Jika pengguna menekan "Cancel"
swal("Data tidak jadi dihapus!", {
icon: "error",
});
}
});
}
</script>
@endsection
Langkah 5: Menambahkan Menu Peminjaman di Sidebar
Agar halaman daftar peminjaman bisa diakses, kita perlu menambahkan link menunya. Sesuai rencana, kita akan membuat grup menu baru bernama "Transaksi" agar navigasi aplikasi kita lebih terstruktur.
<ul id="sidebarnav">
{{-- MENU HOME --}}
<li class="nav-small-cap">
<i class="ti ti-dots nav-small-cap-icon fs-4"></i>
<span class="hide-menu">Home</span>
</li>
<li class="sidebar-item {{ Request::is('dashboard') ? 'selected' : '' }}">
<a class="sidebar-link {{ Request::is('dashboard') ? 'active' : '' }}"
href="{{ route('dashboard') }}" aria-expanded="false">
<span><i class="ti ti-layout-dashboard"></i></span>
<span class="hide-menu">Dashboard</span>
</a>
</li>
{{-- MENU DATAMASTER --}}
<li class="nav-small-cap">
<i class="ti ti-dots nav-small-cap-icon fs-4"></i>
<span class="hide-menu">Datamaster</span>
</li>
{{-- Menu Users, Category, Item --}}
<li class="sidebar-item {{ Request::is('users*') ? 'selected' : '' }}">
<a class="sidebar-link {{ Request::is('users*') ? 'active' : '' }}"
href="{{ route('users.index') }}" aria-expanded="false">
<span><i class="ti ti-users"></i></span>
<span class="hide-menu">Data Users</span>
</a>
</li>
<li class="sidebar-item {{ Request::is('category*') ? 'selected' : '' }}">
<a class="sidebar-link {{ Request::is('category*') ? 'active' : '' }}"
href="{{ route('category.index') }}" aria-expanded="false">
<span><i class="ti ti-category"></i></span>
<span class="hide-menu">Data Category</span>
</a>
</li>
<li class="sidebar-item {{ Request::is('item*') ? 'selected' : '' }}">
<a class="sidebar-link {{ Request::is('item*') ? 'active' : '' }}"
href="{{ route('item.index') }}" aria-expanded="false">
<span><i class="ti ti-box"></i></span>
<span class="hide-menu">Data Item</span>
</a>
</li>
{{-- (BARU) MENU TRANSAKSI --}}
<li class="nav-small-cap">
<i class="ti ti-dots nav-small-cap-icon fs-4"></i>
<span class="hide-menu">Transaksi</span>
</li>
<li class="sidebar-item {{ Request::is('loan*') ? 'selected' : '' }}">
<a class="sidebar-link {{ Request::is('loan*') ? 'active' : '' }}"
href="{{ route('loan.index') }}" aria-expanded="false">
<span><i class="ti ti-clipboard-text"></i></span>
<span class="hide-menu">Peminjaman</span>
</a>
</li>
</ul>
Form ini akan menjadi yang paling interaktif karena akan mengambil data dari tabel users dan items untuk ditampilkan sebagai pilihan dropdown.
use App\Models\User;
use App\Models\Item;
public function create()
{
$data['title'] = $this->title;
$data['menu'] = $this->menu;
// Ambil data user yang rolenya siswa
$data['users'] = User::where('role', 'Siswa')->get();
// Ambil semua data item
$data['items'] = Item::all();
return view($this->directory . '.create', $data);
}
@extends('admin.layouts.app')
@section('css')
{{-- CSS Tambahan --}}
@endsection
@section('content')
<div class="card">
<div class="card-body">
<h5 class="card-title fw-semibold mb-4">Tambah Data {{ $title }}</h5>
<div class="card">
<div class="card-body">
<form action="{{ route('loan.store') }}" method="POST">
@csrf
{{-- Nama Peminjam --}}
<div class="mb-3">
<label for="user_id" class="form-label">Nama Peminjam</label>
<select class="form-select @error('user_id') is-invalid @enderror" name="user_id" id="user_id">
<option value="" disabled selected>Pilih Peminjam</option>
@foreach ($users as $user)
<option value="{{ $user->id }}" {{ old('user_id') == $user->id ? 'selected' : '' }}>{{ $user->name }}</option>
@endforeach
</select>
@error('user_id')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Nama Barang --}}
<div class="mb-3">
<label for="item_id" class="form-label">Nama Barang</label>
<select class="form-select @error('item_id') is-invalid @enderror" name="item_id" id="item_id">
<option value="" disabled selected>Pilih Barang</option>
@foreach ($items as $item)
<option value="{{ $item->id }}" {{ old('item_id') == $item->id ? 'selected' : '' }}>{{ $item->name }} - ({{$item->unique_code}})</option>
@endforeach
</select>
@error('item_id')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tanggal Pinjam --}}
<div class="mb-3">
<label for="loan_date" class="form-label">Tanggal Pinjam</label>
<input type="date" class="form-control @error('loan_date') is-invalid @enderror" name="loan_date"
id="loan_date" value="{{ old('loan_date') }}">
@error('loan_date')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tanggal Pengembalian --}}
<div class="mb-3">
<label for="return_date" class="form-label">Tanggal Pengembalian</label>
<input type="date" class="form-control @error('return_date') is-invalid @enderror" name="return_date"
id="return_date" value="{{ old('return_date') }}">
@error('return_date')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tombol --}}
<button type="submit" class="btn btn-primary">Simpan</button>
<a href="{{ route('loan.index') }}" class="btn btn-warning">Kembali</a>
</form>
</div>
</div>
</div>
</div>
@endsection
@section('js')
{{-- JS Tambahan --}}
@endsection
Logika ini akan sedikit lebih kompleks, karena kita harus memeriksa ketersediaan barang sebelum menyimpannya.
public function store(Request $request)
{
// 1. Validasi data
$validatedData = $request->validate([
'user_id' => 'required',
'item_id' => 'required',
'loan_date' => 'required|date',
'return_date' => 'required|date|after_or_equal:loan_date',
]);
// 2. Cek apakah barang sedang dipinjam atau rusak
$item = Item::findOrFail($validatedData['item_id']);
if ($item->condition === 'Rusak') {
return redirect()->route('loan.create')->withInput()->with([
'status' => 'danger', 'title' => 'Gagal', 'message' => 'Barang dalam kondisi rusak dan tidak bisa dipinjam.'
]);
}
$isBorrowed = Loan::where('item_id', $validatedData['item_id'])->where('status', 'Dipinjam')->exists();
if ($isBorrowed) {
return redirect()->route('loan.create')->withInput()->with([
'status' => 'danger', 'title' => 'Gagal', 'message' => 'Barang ini sedang dipinjam oleh orang lain.'
]);
}
// 3. Simpan data ke database
$loan = Loan::create($validatedData);
// 4. Redirect dengan pesan sukses
if ($loan) {
return redirect()->route('loan.index')->with([
'status' => 'success',
'title' => 'Berhasil',
'message' => 'Data Peminjaman Berhasil Ditambahkan!'
]);
} else {
return redirect()->route('loan.index')->with([
'status' => 'danger',
'title' => 'Gagal',
'message' => 'Data Peminjaman Gagal Ditambahkan!'
]);
}
}
Penjelasan Baru:
Langkah 9: Membuat Form Ubah Peminjaman
Prosesnya akan sangat mirip dengan membuat form tambah, kita akan mengadaptasi kode yang sudah ada untuk mempercepat pekerjaan.
public function edit(Loan $loan)
{
$data['title'] = $this->title;
$data['menu'] = $this->menu;
// Cari data peminjaman berdasarkan ID menggunakan Model Binding
$data['loan'] = $loan;
// Ambil data user yang rolenya siswa
$data['users'] = User::where('role', 'Siswa')->get();
// Ambil semua data item
$data['items'] = Item::all();
return view($this->directory . '.edit', $data);
}
@extends('admin.layouts.app')
@section('css')
{{-- CSS Tambahan --}}
@endsection
@section('content')
<div class="card">
<div class="card-body">
<h5 class="card-title fw-semibold mb-4">Ubah Data {{ $title }}</h5>
<div class="card">
<div class="card-body">
<form action="{{ route('loan.update', $loan->id) }}" method="POST">
@csrf
@method('PUT')
{{-- Nama Peminjam --}}
<div class="mb-3">
<label for="user_id" class="form-label">Nama Peminjam</label>
<select class="form-select @error('user_id') is-invalid @enderror" name="user_id" id="user_id">
<option value="" disabled>Pilih Peminjam</option>
@foreach ($users as $user)
<option value="{{ $user->id }}" {{ old('user_id', $loan->user_id) == $user->id ? 'selected' : '' }}>{{ $user->name }}</option>
@endforeach
</select>
@error('user_id')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Nama Barang --}}
<div class="mb-3">
<label for="item_id" class="form-label">Nama Barang</label>
<select class="form-select @error('item_id') is-invalid @enderror" name="item_id" id="item_id">
<option value="" disabled>Pilih Barang</option>
@foreach ($items as $item)
<option value="{{ $item->id }}" {{ old('item_id', $loan->item_id) == $item->id ? 'selected' : '' }}>{{ $item->name }} - ({{$item->unique_code}})</option>
@endforeach
</select>
@error('item_id')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tanggal Pinjam --}}
<div class="mb-3">
<label for="loan_date" class="form-label">Tanggal Pinjam</label>
<input type="date" class="form-control @error('loan_date') is-invalid @enderror" name="loan_date"
id="loan_date" value="{{ old('loan_date', \Carbon\Carbon::parse($loan->loan_date)->format('Y-m-d')) }}">
@error('loan_date')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tanggal Pengembalian --}}
<div class="mb-3">
<label for="return_date" class="form-label">Tanggal Pengembalian</label>
<input type="date" class="form-control @error('return_date') is-invalid @enderror" name="return_date"
id="return_date" value="{{ old('return_date', \Carbon\Carbon::parse($loan->return_date)->format('Y-m-d')) }}">
@error('return_date')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
{{-- Tombol --}}
<button type="submit" class="btn btn-primary">Simpan</button>
<a href="{{ route('loan.index') }}" class="btn btn-warning">Kembali</a>
</form>
</div>
</div>
</div>
</div>
@endsection
@section('js')
{{-- JS Tambahan --}}
@endsection
Sekarang kita tulis logika di controller untuk memvalidasi dan memperbarui data di database, termasuk pengecekan jika admin mengganti barang.
public function update(Request $request, Loan $loan)
{
// 1. Gunakan Route Model Binding, variabel $loan sudah siap pakai.
$validatedData = $request->validate([
'user_id' => 'required',
'item_id' => 'required',
'loan_date' => 'required|date',
'return_date' => 'required|date|after_or_equal:loan_date',
]);
// 2. Jalankan pengecekan ketersediaan HANYA JIKA item pinjaman diubah.
if ($loan->item_id != $validatedData['item_id']) {
$newItem = Item::findOrFail($validatedData['item_id']);
// Cek jika item baru dalam kondisi rusak.
if ($newItem->condition === 'Rusak') {
return redirect()->back()->withInput()->with([
'status' => 'danger', 'title' => 'Gagal', 'message' => 'Barang baru yang dipilih dalam kondisi rusak.'
]);
}
// Cek jika item baru sedang dipinjam oleh orang lain.
$isBorrowed = Loan::where('item_id', $validatedData['item_id'])->where('status', 'Dipinjam')->exists();
if ($isBorrowed) {
return redirect()->back()->withInput()->with([
'status' => 'danger', 'title' => 'Gagal', 'message' => 'Barang baru yang dipilih sedang dipinjam.'
]);
}
}
// 3. Update data peminjaman di database.
$updateProcess = $loan->update($validatedData);
// 4. Redirect dengan pesan status berdasarkan hasil update.
if ($updateProcess) {
return redirect()->route('loan.index')->with([
'status' => 'success',
'title' => 'Berhasil',
'message' => 'Data Peminjaman Berhasil Diubah!'
]);
} else {
return redirect()->route('loan.index')->with([
'status' => 'danger',
'title' => 'Gagal',
'message' => 'Data Peminjaman Gagal Diubah!'
]);
}
}
Penjelasan Perubahan:
Kita menambahkan blok if ($loan->item_id != $validatedData['item_id']). Kode di dalam blok ini hanya akan berjalan jika admin memilih barang yang berbeda dari yang tercatat sebelumnya, untuk memastikan barang baru tersebut memang tersedia.
Ini adalah langkah terakhir untuk melengkapi CRUD Peminjaman. Kita hanya perlu mengisi logika di controller, karena route dan tombol di tampilan sudah kita siapkan.
public function destroy(Loan $loan)
{
// 1. Gunakan Route Model Binding, variabel $loan sudah siap pakai untuk hapus data peminjaman.
$deleteProcess = $loan->delete();
// 2. Redirect dengan pesan status berdasarkan hasil proses hapus.
if ($deleteProcess) {
return redirect()->route('loan.index')->with([
'status' => 'success',
'title' => 'Berhasil',
'message' => 'Data Peminjaman Berhasil Dihapus!'
]);
} else {
return redirect()->route('loan.index')->with([
'status' => 'danger',
'title' => 'Gagal',
'message' => 'Data Peminjaman Gagal Dihapus!'
]);
}
}
Penjelasan Kode: Logikanya sangat sederhana. Fungsi ini mencari data peminjaman berdasarkan ID, menghapusnya dari database menggunakan metode $loan->delete(), lalu mengembalikan pengguna ke halaman daftar peminjaman dengan notifikasi yang sesuai.
Saatnya memastikan semua bagian (Tombol -> SweetAlert -> Controller -> Hapus Data -> Redirect) bekerja dengan sempurna.
Route Resource yang kita buat sebelumnya sudah menyediakan "pintu" untuk halaman detail, yaitu loan.show yang mengarah ke fungsi show() di controller. Mari kita isi fungsinya.
public function show(Loan $loan)
{
// 1. Gunakan Route Model Binding, variabel $loan sudah siap pakai.
// Tidak perlu lagi mencari manual dengan findOrFail().
// 2. Siapkan data umum.
$data['title'] = $this->title;
$data['menu'] = $this->menu;
// 3. Muat relasi (eager load) ke dalam model $loan yang sudah ada.
$loan->load(['user', 'item.category']);
$data['loan'] = $loan;
// 4. Kirim semua data ke view.
return view($this->directory . '.show', $data);
}
Penjelasan Kode: Perhatikan .with(['user', 'item.category']). Ini adalah nested eager loading. Artinya: "Ambil data peminjaman, sertakan data user-nya, dan sertakan juga data item-nya, lalu untuk item tersebut, sertakan juga data category-nya".
Sekarang kita akan membuat halaman baru untuk menampilkan detail peminjaman dan barang.
@extends('admin.layouts.app')
@section('css')
{{-- CSS Tambahan --}}
@endsection
@section('content')
<div class="row">
{{-- KOLOM KIRI: DETAIL PEMINJAMAN --}}
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title fw-semibold mb-4">Detail Peminjaman</h5>
<table class="table table-striped table-bordered-0">
<tbody>
<tr>
<th>Nama Peminjam</th>
<td>{{ $loan->user->name }}</td>
</tr>
<tr>
<th>Tanggal Pinjam</th>
<td>{{ \Carbon\Carbon::parse($loan->loan_date)->format('d F Y') }}</td>
</tr>
<tr>
<th>Tgl Wajib Kembali</th>
<td>{{ \Carbon\Carbon::parse($loan->return_date)->format('d F Y') }}</td>
</tr>
<tr>
<th>Tanggal Aktual Kembali</th>
<td>
@if ($loan->actual_return_date)
{{ \Carbon\Carbon::parse($loan->actual_return_date)->format('d F Y') }}
@else
-
@endif
</td>
</tr>
<tr>
<th>Status</th>
<td>
@if ($loan->status == 'Dipinjam')
<span class="badge bg-warning">{{ $loan->status }}</span>
@else
<span class="badge bg-success">{{ $loan->status }}</span>
@endif
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{{-- KOLOM KANAN: DETAIL BARANG --}}
<div class="col-md-6">
<div class="card">
<div class="card-body">
<h5 class="card-title fw-semibold mb-4">Detail Barang</h5>
@if ($loan->item->photo)
<div class="mb-3 text-center">
<img src="{{ asset('photos/' . $loan->item->photo) }}" alt="Foto Barang" class="img-fluid rounded" style="max-height: 200px;">
</div>
@endif
<table class="table table-striped table-bordered-0">
<tbody>
<tr>
<th>Nama Barang</th>
<td>{{ $loan->item->name }}</td>
</tr>
<tr>
<th>Kategori</th>
<td>{{ $loan->item->category->name }}</td>
</tr>
<tr>
<th>Kode Unik</th>
<td>{{ $loan->item->unique_code }}</td>
</tr>
<tr>
<th>Kondisi</th>
<td>{{ $loan->item->condition }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{{-- TOMBOL AKSI --}}
<div class="card">
<div class="card-body">
<div class="mt-3 d-flex justify-content-between">
<a href="{{ route('loan.index') }}" class="btn btn-warning">Kembali</a>
{{-- Tombol ini hanya muncul jika status masih 'Dipinjam' --}}
@if ($loan->status == 'Dipinjam')
<form action="#" method="POST">
@csrf
<button type="submit" class="btn btn-success">Kembalikan Barang</button>
</form>
@endif
</div>
</div>
</div>
@endsection
@section('js')
{{-- JS Tambahan --}}
@endsection
Agar bisa masuk ke halaman detail, kita akan menambahkan tombol "Detail" di halaman daftar peminjaman, di samping tombol "Ubah" dan "Hapus".
<td>
<a href="{{ route('loan.edit', $loan->id) }}" class="btn btn-warning btn-sm">Ubah</a>
<form ... > ... </form>
</td>
<td>
<a href="{{ route('loan.show', $loan->id) }}" class="btn btn-info btn-sm">Detail</a>
<a href="{{ route('loan.edit', $loan->id) }}" class="btn btn-warning btn-sm">Ubah</a>
<form id="deleteForm{{ $loan->id }}"
action="{{ route('loan.destroy', $loan->id) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="button" class="btn btn-danger btn-sm"
onclick="confirmDelete({{ $loan->id }})">Hapus</button>
</form>
</td>
Sekarang kita akan membuat tombol "Kembalikan Barang" di halaman detail berfungsi. Ini memerlukan route khusus dan method baru di controller.
Route::middleware('auth')->group(function () {
// ...
Route::resource('loan', LoanController::class);
Route::put('loan/{loan}/return', [LoanController::class, 'returnItem'])->name('loan.return');
});
public function returnItem(Loan $loan)
{
// 1. Gunakan Route Model Binding, variabel $loan sudah siap pakai.
// Tidak perlu lagi mencari manual dengan findOrFail().
// 2. Cek apakah barang sudah pernah dikembalikan.
if ($loan->status == 'Dikembalikan') {
return redirect()->route('loan.index')->with([
'status' => 'info',
'title' => 'Informasi',
'message' => 'Barang ini sudah dikembalikan sebelumnya.'
]);
}
// 3. Update status peminjaman dan tanggal pengembalian aktual.
$loan->status = 'Dikembalikan';
$loan->actual_return_date = now();
$updateProcess = $loan->save();
// 4. Redirect dengan pesan status berdasarkan hasil proses simpan.
if ($updateProcess) {
return redirect()->route('loan.index')->with([
'status' => 'success',
'title' => 'Berhasil',
'message' => 'Barang telah berhasil dikembalikan!'
]);
} else {
return redirect()->route('loan.index')->with([
'status' => 'danger',
'title' => 'Gagal',
'message' => 'Proses pengembalian barang gagal.'
]);
}
}
<form action="{{ route('loan.return', $loan->id) }}" method="POST">
@csrf
@method('PUT')
<button type="submit" class="btn btn-success">Kembalikan Barang</button>
</form>
Saatnya menguji keseluruhan alur dari fitur baru kita.
Selamat! Anda telah berhasil membangun fungsionalitas CRUD yang lengkap, ditambah dengan fitur kustom untuk proses bisnis spesifik (pengembalian barang). Ini adalah pencapaian besar dalam bagian MEMBUAT HALAMAN TRANSAKSI PEMINJAMAN (LOAN).
Artikel Lainnya Dengan Kategori Terkait :
1. Inventaris Lab Laravel 12 : Bagian #01 - INSTALASI LARAGON, PHP, PHPMYADMIN & LARAVEL
2. Inventaris Lab Laravel 12 : Bagian #02 - KONFIGURASI DATABASE & FONDASI PROYEK
3. Inventaris Lab Laravel 12 : Bagian #03 - MEMBANGUN HALAMAN ADMIN DENGAN BLADE TEMPLATING
4. Inventaris Lab Laravel 12 : Bagian #04 - MEMBUAT HALAMAN DASHBOARD DINAMIS
5. Inventaris Lab Laravel 12 : Bagian #05 - MEMBUAT HALAMAN CRUD USERS
6. Inventaris Lab Laravel 12 : Bagian #06 - MEMBUAT FITUR AUTENTIKASI (LOGIN) & PENYESUAIAN UI
7. Inventaris Lab Laravel 12 : Bagian #07 - MEMBUAT HALAMAN CRUD CATEGORY
8. Inventaris Lab Laravel 12 : Bagian #08 - MEMBUAT HALAMAN CRUD ITEM
9. Inventaris Lab Laravel 12 : Bagian #09 - MEMBUAT HALAMAN TRANSAKSI PEMINJAMAN (LOAN)
10. Inventaris Lab Laravel 12 : Bagian #10 - HAK AKSES (AUTHORIZATION) & HALAMAN SISWA
Mahardika Oktadiansyah - 15 Juli 2025
Belajar CSS Lanjutan #395 | CSS padding-inline Property
Mahardika Oktadiansyah - 15 Juli 2025
Belajar CSS Lanjutan #394 | CSS padding-bottom Property
Mahardika Oktadiansyah - 15 Juli 2025
Belajar CSS Lanjutan #393 | CSS padding-block-start Property