Bagian 1 dari seri

Persiapan Proyek dan Login Sistem Kasir Laravel

Diterbitkan 15 September 2026

Bagian ini menghasilkan proyek Laravel dengan login administrator dan kasir, pembatasan akses, dashboard, serta layout Bootstrap CDN.

Membuat Proyek dan Database

composer create-project laravel/laravel kasir-laravel "^13.0"
cd kasir-laravel
php artisan key:generate
CREATE DATABASE kasir_laravel CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Isi koneksi pada .env:

APP_NAME="Kasir Laravel"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000
APP_LOCALE=id
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=kasir_laravel
DB_USERNAME=root
DB_PASSWORD=
SESSION_DRIVER=database

Tambahkan kolom pengguna:

php artisan make:migration add_role_and_is_active_to_users_table

Isi method up() dan down() migration tersebut:

public function up(): void
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('role', 20)->default('cashier')->after('password');
        $table->boolean('is_active')->default(true)->after('role');
    });
}

public function down(): void
{
    Schema::table('users', fn (Blueprint $table) => $table->dropColumn(['role', 'is_active']));
}

Jalankan php artisan migrate.

Model User

Isi app/Models/User.php:

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;
    protected $fillable = ['name', 'email', 'password', 'role', 'is_active'];
    protected $hidden = ['password', 'remember_token'];
    protected function casts(): array
    {
        return ['email_verified_at' => 'datetime', 'password' => 'hashed', 'is_active' => 'boolean'];
    }
    public function isAdmin(): bool { return $this->role === 'admin'; }
}

Login Controller

Buat php artisan make:controller AuthController, lalu isi:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    public function create() { return view('auth.login'); }
    public function store(Request $request)
    {
        $credentials = $request->validate(['email' => ['required','email'], 'password' => ['required','string']]);
        if (!Auth::attempt([...$credentials, 'is_active' => true], $request->boolean('remember'))) {
            return back()->withErrors(['email' => 'Email atau password salah, atau akun tidak aktif.'])->onlyInput('email');
        }
        $request->session()->regenerate();
        return redirect()->intended(route('dashboard'));
    }
    public function destroy(Request $request)
    {
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        return redirect()->route('login');
    }
}

Route

Isi routes/web.php:

<?php
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

Route::redirect('/', '/dashboard');
Route::middleware('guest')->group(function () {
    Route::get('login', [AuthController::class, 'create'])->name('login');
    Route::post('login', [AuthController::class, 'store'])->middleware('throttle:5,1')->name('login.store');
});
Route::middleware('auth')->group(function () {
    Route::view('dashboard', 'dashboard')->name('dashboard');
    Route::post('logout', [AuthController::class, 'destroy'])->name('logout');
});

Layout Bootstrap

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

<!doctype html><html lang="id"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title', 'Dashboard') - {{ config('app.name') }}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
<style>body{background:#f4f7fb}.card{border:0;box-shadow:0 .25rem 1rem #0f172a14}@media print{.d-print-none,.navbar{display:none!important}}</style>
@stack('styles')</head><body>
<nav class="navbar navbar-dark bg-primary d-print-none"><div class="container">
<a class="navbar-brand fw-bold" href="{{ route('dashboard') }}">Kasir Laravel</a>
@auth <div class="d-flex align-items-center gap-3 text-white"><span>{{ auth()->user()->name }}</span>
<form method="POST" action="{{ route('logout') }}">@csrf<button class="btn btn-outline-light btn-sm">Logout</button></form></div> @endauth
</div></nav>
<main class="container py-4">
@if(session('success'))<div class="alert alert-success">{{ session('success') }}</div>@endif
@if($errors->any())<div class="alert alert-danger"><ul class="mb-0">@foreach($errors->all() as $error)<li>{{ $error }}</li>@endforeach</ul></div>@endif
@yield('content')</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>@stack('scripts')
</body></html>

Halaman Login dan Dashboard

Buat resources/views/auth/login.blade.php:

<!doctype html><html lang="id"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Login</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"></head>
<body class="bg-light"><main class="container min-vh-100 d-flex align-items-center justify-content-center">
<form method="POST" action="{{ route('login.store') }}" class="card shadow-sm border-0 p-4" style="width:100%;max-width:420px">@csrf
<h1 class="h3">Login Kasir</h1><div class="mb-3"><label class="form-label">Email</label><input type="email" name="email" value="{{ old('email') }}" class="form-control" required autofocus></div>
<div class="mb-3"><label class="form-label">Password</label><input type="password" name="password" class="form-control" required></div>
<label class="form-check mb-3"><input class="form-check-input me-2" type="checkbox" name="remember" value="1"> Ingat saya</label>
<button class="btn btn-primary">Login</button></form></main></body></html>

Buat resources/views/dashboard.blade.php:

@extends('layouts.app')
@section('title','Dashboard')
@section('content')<div class="card"><div class="card-body"><h1 class="h3">Dashboard</h1><p>Selamat datang, {{ auth()->user()->name }}.</p></div></div>@endsection

Akun Administrator

Jalankan php artisan tinker, lalu:

App\Models\User::create(['name'=>'Administrator','email'=>'admin@example.com','password'=>'admin12345','role'=>'admin','is_active'=>true]);

Jalankan php artisan serve, buka http://localhost:8000/login, uji login dan logout. Ganti password demo sebelum aplikasi dipakai di produksi.

Lanjut: Membuat Struktur Database