Skip to main content
Praktikum 9·
10 Juni 2026

STUDI KASUS SISTEM INFORMASI SEKOLAH

REPOSITORY_GITHUB

Praktikum ini merupakan implementasi pengembangan aplikasi web berbasis framework Laravel 9 dengan studi kasus Sistem Informasi Sekolah (Sisfo). Dalam praktikum ini, mahasiswa melakukan serangkaian tahapan mulai dari pembuatan project Laravel baru, konfigurasi koneksi database MySQL, hingga instalasi fitur autentikasi pengguna menggunakan package laravel/ui yang terintegrasi dengan framework CSS Bootstrap. Proses scaffolding autentikasi yang dilakukan secara otomatis menghasilkan controller, model, view, dan route yang siap digunakan, sehingga mahasiswa dapat memahami alur kerja Laravel dalam membangun sistem autentikasi secara efisien tanpa harus membuat dari nol. Selain autentikasi, praktikum ini juga mencakup implementasi sistem templating menggunakan template SB Admin 2 berbasis Bootstrap sebagai antarmuka utama aplikasi. Mahasiswa mempelajari konsep Blade templating engine Laravel — khususnya penggunaan @extends, @yield, @section, dan @include — untuk membangun layout global yang modular (terdiri dari komponen sidebar, topbar, dan konten utama). Di atas fondasi tersebut, dibangun fitur manajemen pengguna (CRUD) lengkap menggunakan Resource Controller, mencakup operasi Create, Read, Update, dan Delete data user dengan dukungan DataTables untuk tampilan tabel yang interaktif.

IIDasar Teori

Laravel Framework adalah framework PHP berbasis MVC (Model-View-Controller) yang dirancang untuk mempercepat dan menyederhanakan pengembangan aplikasi web. Laravel menyediakan berbagai fitur bawaan seperti Eloquent ORM, Blade templating engine, Artisan CLI, routing system, dan manajemen migrasi database. Package laravel/ui adalah paket resmi Laravel yang menyediakan scaffolding antarmuka pengguna menggunakan berbagai framework frontend. Perintah php artisan ui bootstrap --auth secara otomatis men-generate semua file yang dibutuhkan untuk sistem autentikasi (login, register, forgot password) beserta asset Bootstrap yang sudah dikompilasi. Blade adalah templating engine bawaan Laravel. Blade menggunakan sintaks direktif untuk membangun view secara dinamis dan modular. Direktif utama yang digunakan: - @extends('nama.layout') — mewarisi sebuah layout - @yield('nama') — mendefinisikan slot kosong di layout yang akan diisi child view - @section('nama') ... @endsection — mengisi slot @yield dari child view - @include('nama.view') — menyisipkan view lain ke dalam view saat ini Resource Controller adalah controller yang dibuat dengan perintah php artisan make:controller NamaController --resource, yang secara otomatis menghasilkan tujuh method standar CRUD: index, create, store, show, edit, update, dan destroy. Dikombinasikan dengan Route::resource(), seluruh routing CRUD terdefinisi hanya dengan satu baris kode. Migration adalah mekanisme version control untuk skema database di Laravel. Seeder digunakan untuk mengisi data awal ke database secara terprogram, berguna untuk data default seperti akun admin. Eloquent adalah ORM (Object-Relational Mapping) bawaan Laravel yang memungkinkan interaksi dengan database menggunakan sintaks berbasis objek PHP, tanpa menulis query SQL secara langsung.

IVLangkah Kerja Praktikum

1

Membuat Project Laravel 9

Project dibuat menggunakan Composer dengan perintah berikut di dalam folder workspace:

bash
composer create-project laravel/laravel=^9.0 laravel-sisfo --prefer-dist

Setelah selesai, project dijalankan dengan:

bash
php artisan serve
2

Konfigurasi Database

File: .env (di root project)

bash
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_sisfo
DB_USERNAME=root
DB_PASSWORD=

Penjelasan: File .env adalah file konfigurasi environment Laravel. Variabel DB_DATABASE menentukan nama database yang akan digunakan. Karena menggunakan XAMPP dengan konfigurasi default, DB_USERNAME diisi root dan DB_PASSWORD dikosongkan.

3

Instalasi Autentikasi

3.1 Install Package Laravel/UI

bash
composer require laravel/ui

3.2 Generate Scaffolding Autentikasi dengan Bootstrap

bash
php artisan ui bootstrap --auth

Penjelasan: Perintah ini melakukan dua hal sekaligus: menginstal scaffolding Bootstrap sebagai frontend framework, dan men-generate seluruh file autentikasi secara otomatis, meliputi: - Controller: LoginController, RegisterController, ForgotPasswordController, ResetPasswordController, VerificationController, ConfirmPasswordController - View: login.blade.php, register.blade.php, verify.blade.php, beserta view reset password - Layout dasar: app.blade.php, home.blade.php

3.3 Install dan Compile Asset

Penjelasan: Perintah npm install mengunduh seluruh dependensi Node.js yang dibutuhkan Bootstrap. Perintah npm run dev mengkompilasi file-file asset (CSS dan JS) menggunakan Laravel Mix sehingga siap digunakan di browser.

3.4 Menjalankan Migration

bash
php artisan migrate

Penjelasan: Perintah ini menjalankan semua file migration yang ada, membuat tabel-tabel yang dibutuhkan di database: users, password_resets, failed_jobs, dan personal_access_tokens. Jika database belum dibuat, Laravel akan menanyakan apakah ingin dibuat otomatis.

3.5 Tampilan Halaman Autentikasi

Tampilan Halaman Autentikasi view 1
Tampilan Halaman Autentikasi view 2
4

Kustomisasi Tabel Users

bash
Membuat Migration Tambahan

Buka file migration yang baru dibuat di database/migrations/xxxx_costum_table_users.php, kemudian isi dengan kode berikut: File: database/migrations/xxxx_costum_table_users.php

bash
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string("username")->unique();
            $table->string("level");
            $table->enum("status", ["ACTIVE", "INACTIVE"])->default("ACTIVE");
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn("username");
            $table->dropColumn("level");
            $table->dropColumn("status");
        });
    }
};

Penjelasan kode: - Schema::table('users', ...) — memodifikasi tabel users yang sudah ada (bukan membuat baru) - $table->string("username")->unique() — menambah kolom username bertipe VARCHAR(255) dengan constraint UNIQUE agar tidak ada duplikat - $table->string("level") — menambah kolom level untuk menyimpan peran pengguna dalam format JSON - $table->enum("status", ["ACTIVE", "INACTIVE"])->default("ACTIVE") — menambah kolom status dengan nilai terbatas hanya ACTIVE atau INACTIVE, default ACTIVE - Method down() mendefinisikan operasi rollback: menghapus ketiga kolom tersebut

Jalankan migration:

bash
php artisan migrate
Kustomisasi Tabel Users visual reference 7
5

Seeding User Admin

File: database/seeders/AdminSeeder.php — buat dengan perintah php artisan make:seeder AdminSeeder

bash
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class AdminSeeder extends Seeder
{
    public function run()
    {
        $admin = new \App\Models\User;
        $admin->username = "admin";
        $admin->name = "Admin Aplikasi";
        $admin->email = "admin@sisfo.com";
        $admin->level = json_encode(["ADMIN"]);
        $admin->password = \Hash::make("12345678");
        $admin->status = "ACTIVE";
        $admin->save();

        $this->command->info("User Admin berhasil ditambahkan");
    }
}

Penjelasan kode: - new \App\Models\User — membuat instance model Eloquent User - json_encode(["ADMIN"]) — menyimpan level sebagai JSON string karena satu user bisa memiliki lebih dari satu role - \Hash::make("12345678") — mengenkripsi password menggunakan bcrypt sebelum disimpan ke database, sehingga password tidak tersimpan dalam bentuk plain text - $this->command->info(...) — menampilkan pesan ke terminal saat seeder dijalankan

Seeding User Admin visual reference 4

Jalankan seeder:

bash
php artisan db:seed --class=AdminSeeder
Seeding User Admin visual reference 7
6

Templating dengan SB Admin 2

Template SB Admin 2 diunduh dari https://startbootstrap.com/theme/sb-admin-2, diekstrak, lalu seluruh isinya disalin ke folder public/sbadmin di dalam project Laravel.

6.1 Kustomisasi Halaman Login

File: resources/views/layouts/app.blade.php

bash
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Sisfo - Login</title>
    <link href="{{asset('sbadmin/vendor/fontawesome-free/css/all.min.css')}}" rel="stylesheet">
    <link href="{{asset('sbadmin/css/sb-admin-2.min.css')}}" rel="stylesheet">
</head>
<body class="bg-gradient-primary">
<div class="container">
    <div class="row justify-content-center">
        <div class="col-xl-6 col-lg-6 col-md-9">
            <div class="card o-hidden border-0 shadow-lg my-5">
                <div class="card-body p-0">
                    <div class="row">
                        <div class="col-lg-12 text-center">
                            <div class="p-5">
                                <div class="text-center">
                                    <h1 class="h4 text-gray-900 mb-4">Halaman Login</h1>
                                </div>
                                <form class="user" method="POST" action="{{ route('login') }}">
                                    @csrf
                                    <div class="form-group">
                                        <input id="email" type="email"
                                            class="form-control form-control-user @error('email') is-invalid @enderror"
                                            name="email" value="{{ old('email') }}" required autofocus/>
                                        @error('email')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                    <div class="form-group">
                                        <input id="password" type="password"
                                            class="form-control form-control-user @error('password') is-invalid @enderror"
                                            name="password" required />
                                        @error('password')
                                            <span class="invalid-feedback" role="alert">
                                                <strong>{{ $message }}</strong>
                                            </span>
                                        @enderror
                                    </div>
                                    <button type="submit" class="btn btn-primary btn-user btn-block">
                                        Login
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="{{asset('sbadmin/vendor/jquery/jquery.min.js')}}"></script>
<script src="{{asset('sbadmin/vendor/bootstrap/js/bootstrap.bundle.min.js')}}"></script>
<script src="{{asset('sbadmin/vendor/jquery-easing/jquery.easing.min.js')}}"></script>
<script src="{{asset('sbadmin/js/sb-admin-2.min.js')}}"></script>
</body>
</html>

Penjelasan kode: - class="bg-gradient-primary" pada <body> — menerapkan background gradasi biru dari SB Admin 2 - {{asset('sbadmin/...')}} — helper Laravel untuk menghasilkan URL absolut ke file di folder public/sbadmin - {{ route('login') }} — helper Laravel untuk menghasilkan URL berdasarkan nama route, bukan hardcode URL - @csrf — direktif Blade yang menyisipkan hidden input token CSRF untuk keamanan form - @error('email') ... @enderror — direktif Blade untuk menampilkan pesan error validasi pada field tertentu

Kustomisasi Halaman Login view 4

6.2 Layout Global (main.blade.php)

File: resources/views/layouts/main.blade.php (buat file baru)

bash
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Sisfo - @yield('judul')</title>
    <link href="{{asset('sbadmin/vendor/fontawesome-free/css/all.min.css')}}" rel="stylesheet">
    <link href="{{asset('sbadmin/css/sb-admin-2.min.css')}}" rel="stylesheet">
    <link href="{{ asset('sbadmin/vendor/datatables/dataTables.bootstrap4.min.css') }}" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
</head>
<body id="page-top">
<div id="wrapper">
    @include("layouts.sidebar")
    <div id="content-wrapper" class="d-flex flex-column">
        <div id="content">
            @include('layouts.topbar')
            <div class="container-fluid">
                <h1 class="h3 mb-4 text-gray-800">@yield("judul")</h1>
                @yield("konten")
            </div>
        </div>
        <footer class="sticky-footer bg-white">
            <div class="container my-auto">
                <div class="copyright text-center my-auto">
                    <span>Copyright &copy; Sisfo</span>
                </div>
            </div>
        </footer>
    </div>
</div>
<a class="scroll-to-top rounded" href="#page-top">
    <i class="fas fa-angle-up"></i>
</a>

<!-- Logout Modal -->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Yakin akan keluar aplikasi ?</h5>
                <button class="close" type="button" data-dismiss="modal">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">Silahkan klik tombol logout untuk keluar aplikasi</div>
            <div class="modal-footer">
                <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
                <form action="{{route('logout')}}" method="POST">
                    @csrf
                    <button class="btn btn-primary">Logout</button>
                </form>
            </div>
        </div>
    </div>
</div>

<script src="{{asset('sbadmin/vendor/jquery/jquery.min.js')}}"></script>
<script src="{{asset('sbadmin/vendor/bootstrap/js/bootstrap.bundle.min.js')}}"></script>
<script src="{{asset('sbadmin/vendor/jquery-easing/jquery.easing.min.js')}}"></script>
<script src="{{asset('sbadmin/js/sb-admin-2.min.js')}}"></script>
<script src="{{ asset('sbadmin/vendor/datatables/jquery.dataTables.min.js') }}"></script>
<script src="{{ asset('sbadmin/vendor/datatables/dataTables.bootstrap4.min.js') }}"></script>
<script src="{{ asset('sbadmin/js/demo/datatables-demo.js') }}"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
    $(document).ready(function() {
        $('.select2-multiple').select2({ placeholder: "Pilih", allowClear: true });
    });
</script>
</body>
</html>

Penjelasan kode: - @yield('judul') di <title> — slot untuk judul halaman yang diisi tiap child view, sehingga tab browser menampilkan judul yang relevan - @include("layouts.sidebar") dan @include('layouts.topbar') — menyisipkan komponen sidebar dan topbar dari file terpisah, menerapkan prinsip DRY (Don't Repeat Yourself) - @yield("konten") — slot utama tempat konten tiap halaman berbeda disisipkan - Modal logout didefinisikan di layout global agar dapat dipanggil dari topbar di halaman manapun

6.3 Komponen Sidebar

File: resources/views/layouts/sidebar.blade.php (buat file baru)

bash
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
    <a class="sidebar-brand d-flex align-items-center justify-content-center" href="#">
        <div class="sidebar-brand-icon rotate-n-15">
            <i class="fas fa-laugh-wink"></i>
        </div>
        <div class="sidebar-brand-text mx-3">Sisfo</div>
    </a>
    <hr class="sidebar-divider my-0">
    <li class="nav-item">
        <a class="nav-link" href="#">
            <i class="fas fa-fw fa-tachometer-alt"></i>
            <span>Dashboard</span>
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="{{ route('users.index') }}">
            <i class="fas fa-fw fa-users"></i>
            <span>Users</span>
        </a>
    </li>
    <hr class="sidebar-divider d-none d-md-block">
    <div class="text-center d-none d-md-inline">
        <button class="rounded-circle border-0" id="sidebarToggle"></button>
    </div>
</ul>

6.4 Komponen Topbar

File: resources/views/layouts/topbar.blade.php (buat file baru)

bash
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
    <button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
        <i class="fa fa-bars"></i>
    </button>
    <ul class="navbar-nav ml-auto">
        <div class="topbar-divider d-none d-sm-block"></div>
        <li class="nav-item dropdown no-arrow">
            @if(\Auth::user())
            <a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
               data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <span class="mr-2 d-none d-lg-inline text-gray-600 small">{{ Auth::user()->name }}</span>
                <img class="img-profile rounded-circle" src="{{ asset('sbadmin/img/undraw_profile.svg') }}">
            </a>
            @endif
            <div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
                <a class="dropdown-item" href="#">
                    <i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i> Profile
                </a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">
                    <i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i> Logout
                </a>
            </div>
        </li>
    </ul>
</nav>

Penjelasan kode: - @if(\Auth::user()) — direktif Blade untuk mengecek apakah user sedang login sebelum menampilkan info pengguna - {{ Auth::user()->name }} — menampilkan nama user yang sedang login dari session autentikasi - data-target="#logoutModal" — menghubungkan tombol logout ke modal konfirmasi yang sudah didefinisikan di main.blade.php

6.5 Penggunaan Layout di Home View

File: resources/views/home.blade.php

bash
@extends('layouts.main')

@section("judul") Dashboard @endsection

@section('konten')
    <p>Dashboard</p>
@endsection

Penjelasan kode: - @extends('layouts.main') — mendeklarasikan bahwa view ini mewarisi layout dari main.blade.php. Seluruh struktur HTML layout (sidebar, topbar, footer, script) akan tersedia secara otomatis. - @section('judul') Dashboard @endsection — mengisi slot @yield('judul') di layout dengan teks "Dashboard" - @section('konten') ... @endsection — mengisi slot @yield('konten') dengan konten spesifik halaman ini

7

Manajemen Users (CRUD)

7.1 Membuat Resource Controller

bash
php artisan make:controller UserController --resource

File: routes/web.php — tambahkan baris berikut:

bash
use App\Http\Controllers\UserController;

Route::resource('users', UserController::class);

Penjelasan: Route::resource() secara otomatis mendaftarkan 7 route sekaligus yang dipetakan ke method di UserController. Hasilnya dapat dilihat dengan php artisan route:list.

7.2 CREATE — Tambah User

File: app/Http/Controllers/UserController.php — method create dan store:

bash
public function create()
{
    return view('user.create');
}

public function store(Request $request)
{
    $user = new \App\Models\User;
    $user->name     = $request->get('nama');
    $user->username = $request->get('username');
    $user->email    = $request->get('email');
    $user->password = \Hash::make($request->get('password'));
    $user->level    = json_encode($request->get('level'));
    $user->status   = "ACTIVE";
    $user->save();

    return redirect()->route('users.index')->with('status', 'User baru berhasil ditambahkan');
}

File: resources/views/user/create.blade.php (buat folder user di dalam views):

bash
@extends('layouts.main')
@section("judul") Create User @endsection
@section('konten')
<div class="card shadow mb-4">
    <div class="card-header py-3"></div>
    <div class="card-body">
        <div class="row">
            <div class="col-lg-9">
                <form method="POST" action="{{ route('users.store') }}">
                    @csrf
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Nama</label>
                        <div class="col-sm-9">
                            <input type="text" class="form-control" name="nama">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Email</label>
                        <div class="col-sm-9">
                            <input type="email" class="form-control" name="email">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Username</label>
                        <div class="col-sm-9">
                            <input type="text" class="form-control" name="username">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Password</label>
                        <div class="col-sm-9">
                            <input type="password" class="form-control" name="password">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Level</label>
                        <div class="col-sm-4">
                            <select class="form-control select2-multiple" name="level[]" multiple="multiple">
                                <option value="ADMIN">ADMIN</option>
                                <option value="GURU">GURU</option>
                                <option value="STAFF">STAFF</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group row">
                        <div class="col-sm-10 text-center">
                            <button type="reset" class="btn btn-warning btn-sm">Batal</button>
                            <button type="submit" class="btn btn-primary btn-sm">Simpan</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
@endsection

Penjelasan kode: - Method create() hanya me-return view form tanpa data tambahan - Method store() mengambil data dari request dengan $request->get('nama_field'), membuat instance model User, mengisi propertinya, lalu menyimpan dengan $user->save() - json_encode($request->get('level')) — field level menerima array dari select multiple, kemudian diencode ke JSON string untuk disimpan di satu kolom - redirect()->route('users.index')->with('status', '...') — setelah simpan, redirect ke halaman list sambil membawa flash message di session - name="level[]" pada select — tanda [] memberitahu PHP bahwa field ini mengirim array nilai

CREATE — Tambah User view 6

7.3 READ — List Users

File: app/Http/Controllers/UserController.php — method index:

bash
public function index()
{
    $users = \App\Models\User::all();
    return view('user.index', ['users' => $users]);
}

File: resources/views/user/index.blade.php:

bash
@extends('layouts.main')
@section("judul") Users @endsection
@section('konten')

@if(session('status'))
    <div class="alert alert-success">{{ session('status') }}</div>
@endif

<p>
    <a href="{{ route('users.create') }}" class="btn btn-primary btn-sm">Tambah User</a>
</p>

<div class="card shadow mb-4">
    <div class="card-header py-3"></div>
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Username</th>
                        <th>Email</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach($users as $user)
                    <tr>
                        <td>{{ $user->name }}</td>
                        <td>{{ $user->username }}</td>
                        <td>{{ $user->email }}</td>
                        <td>
                            <a href="{{ route('users.edit', $user->id) }}" class="btn btn-sm btn-success">Edit</a>
                            <form onsubmit="return confirm('Hapus data user ?')" class="d-inline"
                                  action="{{ route('users.destroy', [$user->id]) }}" method="POST">
                                @csrf
                                <input type="hidden" name="_method" value="DELETE">
                                <input type="submit" value="Hapus" class="btn btn-danger btn-sm">
                            </form>
                        </td>
                    </tr>
                    @endforeach
                </tbody>
            </table>
        </div>
    </div>
</div>
@endsection

Penjelasan kode: - User::all() — mengambil semua data dari tabel users menggunakan Eloquent ORM, mengembalikan Collection - @if(session('status')) — menampilkan flash message dari session jika ada (dikirim oleh redirect ->with('status', '...')) - @foreach($users as $user) — iterasi tiap data user untuk ditampilkan sebagai baris tabel - id="dataTable" — atribut yang diperlukan oleh script DataTables untuk menginisialisasi fitur pencarian, sorting, dan pagination otomatis - Tombol Hapus menggunakan form dengan method="POST" dan hidden input _method=DELETE karena HTML form tidak mendukung method DELETE secara native; Laravel menangani ini melalui method spoofing

READ — List Users view 6

7.4 UPDATE — Edit User

File: app/Http/Controllers/UserController.php — method edit dan update:

bash
public function edit($id)
{
    $user = \App\Models\User::findOrFail($id);
    return view('user.edit', ['user' => $user]);
}

public function update(Request $request, $id)
{
    $user = \App\Models\User::findOrFail($id);
    $user->name  = $request->get('nama');
    $user->level = json_encode($request->get('level'));
    $user->save();

    return redirect()->route('users.index')->with('status', 'User berhasil diubah');
}

File: resources/views/user/edit.blade.php:

bash
@extends('layouts.main')
@section("judul") Edit User @endsection
@section('konten')
<div class="card shadow mb-4">
    <div class="card-body">
        <div class="row">
            <div class="col-lg-9">
                <form method="POST" action="{{ route('users.update', [$user->id]) }}">
                    <input type="hidden" name="_method" value="PUT">
                    @csrf
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Nama</label>
                        <div class="col-sm-9">
                            <input type="text" class="form-control" name="nama" value="{{ $user->name }}">
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Email</label>
                        <div class="col-sm-9">
                            <input type="email" class="form-control" name="email" value="{{ $user->email }}" readonly>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Username</label>
                        <div class="col-sm-9">
                            <input type="text" class="form-control" name="username" value="{{ $user->username }}" readonly>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-sm-3 col-form-label">Level</label>
                        <div class="col-sm-4">
                            <select class="form-control select2-multiple" name="level[]" multiple="multiple">
                                <option value="ADMIN" {{ in_array("ADMIN", json_decode($user->level)) ? "selected" : "" }}>ADMIN</option>
                                <option value="GURU"  {{ in_array("GURU",  json_decode($user->level)) ? "selected" : "" }}>GURU</option>
                                <option value="STAFF" {{ in_array("STAFF", json_decode($user->level)) ? "selected" : "" }}>STAFF</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group row">
                        <div class="col-sm-10 text-center">
                            <a href="{{ route('users.index') }}" class="btn btn-warning btn-sm">Batal</a>
                            <button type="submit" class="btn btn-primary btn-sm">Simpan</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
@endsection

Penjelasan kode: - findOrFail($id) — mengambil data user berdasarkan ID; jika tidak ditemukan, otomatis melempar error 404 (lebih aman daripada find() yang mengembalikan null) - <input type="hidden" name="_method" value="PUT"> — method spoofing untuk mengirim request PUT melalui form HTML - value="{{ $user->name }}" — mengisi nilai default form dengan data yang sudah ada di database - in_array("ADMIN", json_decode($user->level)) ? "selected" : "" — logika untuk menandai option yang sesuai dengan level user saat ini; json_decode mengubah JSON string kembali menjadi array PHP

UPDATE — Edit User view 6
UPDATE — Edit User view 7

7.5 DELETE — Hapus User

Tombol hapus sudah disertakan di user/index.blade.php (lihat langkah READ). Berikut method destroy di controller: File: app/Http/Controllers/UserController.php — method destroy:

bash
public function destroy($id)
{
    $user = \App\Models\User::findOrFail($id);
    $user->delete();

    return redirect()->route('users.index')->with('status', 'User berhasil dihapus');
}

Penjelasan kode: - findOrFail($id) — memastikan data ada sebelum mencoba menghapus - $user->delete() — menghapus record dari database menggunakan Eloquent; query DELETE FROM users WHERE id = ? dieksekusi secara otomatis di balik layar - Setelah penghapusan, dilakukan redirect dengan flash message sukses

DELETE — Hapus User view 4
DELETE — Hapus User view 5

VIKesimpulan

Dari praktikum ini dapat disimpulkan beberapa hal sebagai berikut: Pertama, Laravel 9 menyediakan mekanisme scaffolding autentikasi yang sangat efisien melalui package laravel/ui. Dengan hanya menjalankan tiga perintah Artisan dan satu perintah NPM, seluruh infrastruktur autentikasi (controller, view, route, migration) ter-generate secara otomatis, mempercepat proses development secara signifikan. Kedua, sistem Blade templating engine Laravel memungkinkan pemisahan komponen UI secara modular melalui direktif @extends, @yield, @section, dan @include. Pendekatan ini menghasilkan kode yang lebih terstruktur, mudah dipelihara, dan menghindari duplikasi karena perubahan pada layout global (sidebar, topbar, footer) cukup dilakukan di satu file saja. Ketiga, Resource Controller yang dikombinasikan dengan Route::resource() mengimplementasikan konvensi RESTful secara konsisten. Tujuh endpoint CRUD ter-register hanya dengan satu baris kode routing, dan setiap method memiliki tanggung jawab yang jelas dan terdefinisi dengan baik sesuai prinsip separation of concerns. Keempat, Eloquent ORM menyederhanakan operasi database secara substansial. Operasi seperti User::all(), User::findOrFail($id), $user->save(), dan $user->delete() mengeliminasi kebutuhan penulisan raw SQL query, sekaligus memberikan keamanan tambahan melalui prepared statements otomatis yang mencegah SQL injection.