# 🎯 PENJELASAN DETAIL SETIAP FITUR OCEANGO

---

## 1️⃣ FITUR: REGISTER (Pendaftaran Akun Baru)

### 🎯 Fungsi Utama:
Memungkinkan pengguna baru mendaftar akun untuk menggunakan sistem Oceango

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/register`
- File: `resources/views/login/register.blade.php`
- Controller: `app/Http/Controllers/AuthController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER BUKA HALAMAN REGISTER
└─ Masuk ke URL /register
└─ Lihat form dengan field: Nama, Email, Password, Konfirmasi Password

STEP 2: USER ISI FORM
└─ Nama: Contoh "Budi Santoso"
└─ Email: Contoh "budi@gmail.com"
└─ Password: Contoh "Rahasia123"
└─ Konfirmasi Password: "Rahasia123"

STEP 3: VALIDASI INPUT (Backend)
Sistem check:
✅ Email sudah terdaftar? (jika ya → error)
✅ Email format valid? (jika tidak → error)
✅ Password minimal 8 karakter? (jika tidak → error)
✅ Password & konfirmasi sama? (jika tidak → error)

STEP 4: SIMPAN KE DATABASE
Jika semua validasi OK:
```
INSERT INTO users (name, email, password, role, created_at, updated_at)
VALUES (
  'Budi Santoso',
  'budi@gmail.com',
  '$2y$12$hash_password_yang_di_encrypt', ← Password di-hash dengan Bcrypt
  'user',                                  ← Default role = user
  '2026-06-02 10:00:00',
  '2026-06-02 10:00:00'
);
```

STEP 5: REDIRECT & SUCCESS MESSAGE
└─ Redirect ke halaman login
└─ Tampilkan pesan: "Registrasi berhasil! Silakan login"
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/AuthController.php
public function register(Request $request)
{
    // Validasi input
    $validated = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users,email', // Email harus unik
        'password' => 'required|string|min:8|confirmed', // Min 8 char & match confirmation
    ]);

    // Create user dengan role 'user'
    User::create([
        'name' => $validated['name'],
        'email' => $validated['email'],
        'password' => bcrypt($validated['password']), // Hash password
        'role' => 'user', // Default role
    ]);

    return redirect('/login')->with('success', 'Registrasi berhasil!');
}
```

### 📸 Form Register Terlihat Seperti:
```
┌─────────────────────────────────────┐
│      DAFTAR AKUN OCEANGO           │
├─────────────────────────────────────┤
│                                     │
│ Nama Lengkap:                       │
│ [_____________________________]     │
│                                     │
│ Email:                              │
│ [_____________________________]     │
│                                     │
│ Password:                           │
│ [_____________________________]     │
│                                     │
│ Konfirmasi Password:                │
│ [_____________________________]     │
│                                     │
│        [ DAFTAR ]                  │
│                                     │
│ Sudah punya akun? Login di sini    │
│                                     │
└─────────────────────────────────────┘
```

### ❌ Contoh Error:
```
Skenario 1: Email sudah terdaftar
Input: budi@gmail.com (email sudah ada)
Output: ❌ "Email sudah terdaftar. Gunakan email lain."

Skenario 2: Password tidak cocok
Input: Password="Rahasia123", Konfirmasi="Rahasia456"
Output: ❌ "Password tidak cocok"

Skenario 3: Password terlalu pendek
Input: Password="123"
Output: ❌ "Password minimal 8 karakter"
```

---

## 2️⃣ FITUR: LOGIN (Masuk Akun)

### 🎯 Fungsi Utama:
Memverifikasi email dan password pengguna, kemudian membuat session untuk akses area yang dilindungi

### 📍 Lokasi:
- User URL: `http://127.0.0.1:8000/login`
- Admin URL: `http://127.0.0.1:8000/admin/login`
- Controller: `app/Http/Controllers/AuthController.php` (user), `AdminAuthController.php` (admin)

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER BUKA HALAMAN LOGIN
└─ Masuk ke URL /login
└─ Lihat form dengan field: Email, Password

STEP 2: USER ISI EMAIL & PASSWORD
├─ Email: budi@gmail.com
└─ Password: Rahasia123

STEP 3: SUBMIT FORM
└─ System melakukan query ke database:
   SELECT * FROM users WHERE email = 'budi@gmail.com'

STEP 4: VERIFIKASI PASSWORD
└─ Database menemukan user dengan email tersebut
└─ Ambil password yang ter-hash: $2y$12$XYZ...
└─ Compare password input dengan yang tersimpan:
   bcrypt('Rahasia123') == '$2y$12$XYZ...' ?
   
STEP 5a: JIKA PASSWORD BENAR ✅
└─ Create session dengan user id
└─ Set session timeout: 120 menit
└─ Redirect ke dashboard
└─ User sudah authenticated

STEP 5b: JIKA PASSWORD SALAH ❌
└─ Tampilkan error: "Email atau password salah"
└─ Redirect kembali ke login
└─ User belum authenticated
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/AuthController.php
public function login(Request $request)
{
    // Validasi input
    $credentials = $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    // Attempt login
    if (Auth::attempt($credentials)) {
        // Password benar, session created
        $request->session()->regenerate();
        return redirect('/my-bookings')->with('success', 'Login berhasil!');
    }

    // Password salah
    return back()->withErrors([
        'email' => 'Email atau password salah',
    ]);
}
```

### 🔐 Apa itu Session?
```
SESSION = Data temporary yang menyimpan informasi user yang login

Contoh:
1. User login dengan email: budi@gmail.com
2. Server create session dengan:
   - session_id: abcd1234efgh5678
   - user_id: 5
   - user_name: Budi Santoso
   - timestamp: 2026-06-02 10:30:00

3. Session disimpan di:
   - Browser (cookie)
   - Server (session file)

4. Setiap kali user akses halaman protected:
   - Browser kirim session_id di cookie
   - Server check: session_id valid? user_id siapa?
   - Jika valid → tampilkan halaman
   - Jika invalid → redirect ke login

5. Session timeout:
   - Default: 120 menit
   - Jika user tidak active > 120 menit → session expired
   - User harus login lagi
```

### 📸 Form Login:
```
┌─────────────────────────────────────┐
│        LOGIN OCEANGO               │
├─────────────────────────────────────┤
│                                     │
│ Email:                              │
│ [_____________________________]     │
│                                     │
│ Password:                           │
│ [_____________________________]     │
│ Lupa password? Klik di sini        │
│                                     │
│        [ LOGIN ]                   │
│                                     │
│ Belum punya akun? Daftar di sini   │
│                                     │
│ Login Admin? Klik di sini          │
│                                     │
└─────────────────────────────────────┘
```

---

## 3️⃣ FITUR: PESAN TIKET KAPAL (Create Booking)

### 🎯 Fungsi Utama:
Memungkinkan user membuat booking baru untuk memesan tiket kapal

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/my-bookings/pesan`
- File: `resources/views/user/bookings/create.blade.php`
- Controller: `app/Http/Controllers/UserBookingController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER KLIK TOMBOL "PESAN TIKET BARU"
└─ Redirect ke /my-bookings/pesan
└─ Tampilkan form kosong

STEP 2: USER ISI FORM PEMESANAN
├─ Rute Asal: Jakarta
├─ Rute Tujuan: Surabaya
├─ Tanggal Keberangkatan: 10 Juni 2026
├─ Jumlah Penumpang: 4 orang
├─ Kelas: Bisnis
├─ Harga: Rp 500.000 (per orang, auto calculate)
└─ Total Harga: Rp 2.000.000 (4 × Rp 500.000)

STEP 3: USER LIHAT PREVIEW HARGA
└─ Form menampilkan kalkulasi:
   Penumpang: 4 orang
   Harga per orang: Rp 500.000
   ────────────────────────────────
   Total Harga: Rp 2.000.000

STEP 4: USER KLIK TOMBOL "PESAN"
└─ Validasi di backend:
   ✅ Semua field terisi?
   ✅ Tanggal valid (tidak di masa lalu)?
   ✅ Penumpang minimal 1?

STEP 5: SISTEM CREATE BOOKING
Database insert:
```
INSERT INTO bookings (
    user_id,        ← 5 (Budi Santoso)
    booking_code,   ← 'OG-20260602-ABC123' (auto-generated)
    route_from,     ← 'Jakarta'
    route_to,       ← 'Surabaya'
    departure_date, ← '2026-06-10 08:00:00'
    passengers,     ← 4
    class,          ← 'bisnis'
    price,          ← 500000 (per orang)
    status,         ← 'pending'
    notes,          ← NULL
    created_at,     ← '2026-06-02 10:30:00'
    updated_at      ← '2026-06-02 10:30:00'
) VALUES (...)
```

STEP 6: REDIRECT KE DETAIL BOOKING
└─ Tampilkan detail booking yang baru dibuat
└─ Tampilkan booking code: OG-20260602-ABC123
└─ Status: PENDING (menunggu approval admin)
└─ Pesan: "Booking berhasil dibuat! Tunggu approval admin"
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/UserBookingController.php
public function store(Request $request)
{
    // Validasi input
    $validated = $request->validate([
        'route_from' => 'required|string',
        'route_to' => 'required|string|different:route_from',
        'departure_date' => 'required|date|after:today',
        'passengers' => 'required|integer|min:1|max:10',
        'class' => 'required|in:ekonomi,bisnis,vip,suite',
        'price' => 'required|numeric|min:100000',
    ]);

    // Create booking (booking_code auto-generate di model)
    $booking = Booking::create([
        'user_id' => auth()->id(),
        'route_from' => $validated['route_from'],
        'route_to' => $validated['route_to'],
        'departure_date' => $validated['departure_date'],
        'passengers' => $validated['passengers'],
        'class' => $validated['class'],
        'price' => $validated['price'],
        'status' => 'pending', // Status default
    ]);

    return redirect()->route('user.bookings.show', $booking)
                   ->with('success', 'Booking berhasil dibuat!');
}
```

### 📸 Form Pemesanan:
```
┌─────────────────────────────────────────────┐
│      PESAN TIKET KAPAL                     │
├─────────────────────────────────────────────┤
│                                             │
│ RUTE:                                       │
│ Dari: [Jakarta________]  Ke: [Surabaya___] │
│                                             │
│ TANGGAL:                                    │
│ [10 Juni 2026_________]                    │
│                                             │
│ PENUMPANG & KELAS:                         │
│ Jumlah Penumpang: [4]  Kelas: [Bisnis ▼] │
│                                             │
│ HARGA:                                      │
│ Harga per orang: Rp 500.000                │
│ Jumlah penumpang: 4 orang                  │
│ ─────────────────────────────────────────  │
│ TOTAL: Rp 2.000.000                        │
│                                             │
│        [ PESAN SEKARANG ]                  │
│                                             │
└─────────────────────────────────────────────┘
```

### 📊 Booking Code Generation:
```
Format: OG-YYYYMMDD-XXXXXX

Contoh Real:
OG-20260602-ABC123
├─ OG = Oceango
├─ 20260602 = 2 Juni 2026
└─ ABC123 = Random 6 karakter uppercase

Setiap booking mendapat unique code:
OG-20260602-ABC123
OG-20260602-XYZ789  (tanggal sama tapi random berbeda)
OG-20260603-QWE456  (tanggal beda)
```

---

## 4️⃣ FITUR: LIHAT RIWAYAT BOOKING (View Bookings)

### 🎯 Fungsi Utama:
Menampilkan daftar semua booking milik user yang login

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/my-bookings/list`
- File: `resources/views/user/bookings/index.blade.php`
- Controller: `app/Http/Controllers/UserBookingController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER KLIK "LIHAT PEMESANAN"
└─ Redirect ke /my-bookings/list
└─ Backend query database:
   SELECT * FROM bookings WHERE user_id = 5 ORDER BY created_at DESC

STEP 2: TAMPILKAN DATA BOOKING
Sistem menampilkan tabel dengan kolom:
```
┌────────────────────────────────────────────────────────────────────┐
│ BOOKING CODE    │ RUTE          │ TGL BERANGKAT │ STATUS  │ AKSI  │
├────────────────────────────────────────────────────────────────────┤
│ OG-20260602-ABC │ Jkt → Sby    │ 10 Juni 2026  │ PENDING │ Lihat │
│ OG-20260601-XYZ │ Sby → Jkt    │ 5 Juni 2026   │ CONFIRM │ Lihat │
│ OG-20260531-QWE │ Jkt → Medan  │ 1 Juni 2026   │ SELESAI │ Lihat │
│ OG-20260530-RTY │ Medan → Jkt  │ 25 Mei 2026   │ BATAL   │ Lihat │
└────────────────────────────────────────────────────────────────────┘

Database query:
```
SELECT 
    id, 
    booking_code, 
    route_from, 
    route_to, 
    departure_date, 
    status, 
    created_at 
FROM bookings 
WHERE user_id = 5 
ORDER BY created_at DESC
LIMIT 10
```

STEP 3: USER KLIK TOMBOL "LIHAT"
└─ Redirect ke detail booking
└─ Tampilkan info lengkap + progress tracking
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/UserBookingController.php
public function index()
{
    // Get semua booking user yang login
    $userId = auth()->id();
    $bookings = Booking::where('user_id', $userId)
                       ->latest() // Order by created_at DESC
                       ->paginate(10); // 10 per halaman

    return view('user.bookings.index', compact('bookings'));
}
```

### 📸 Tampilan Riwayat:
```
MY BOOKINGS - RIWAYAT PEMESANAN SAYA

┌─────────────────────────────────────────────────┐
│  Booking Code      Status    Rute        Tanggal │
├─────────────────────────────────────────────────┤
│  OG-20260602-ABC  ⏳ PENDING Jakarta→Surabaya  │
│                                  10 Juni 2026   │
│                                  [ LIHAT ]      │
├─────────────────────────────────────────────────┤
│  OG-20260601-XYZ  ✅ CONFIRM  Surabaya→Jakarta  │
│                                  5 Juni 2026    │
│                                  [ LIHAT ]      │
├─────────────────────────────────────────────────┤
│  OG-20260531-QWE  ✓ SELESAI  Jakarta→Medan     │
│                                  1 Juni 2026    │
│                                  [ LIHAT ]      │
└─────────────────────────────────────────────────┘
```

---

## 5️⃣ FITUR: TRACKING STATUS (Lihat Progress)

### 🎯 Fungsi Utama:
Menampilkan tracking real-time status perjalanan kapal untuk booking tertentu

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/my-bookings/{booking_id}`
- File: `resources/views/user/bookings/show.blade.php`
- Controller: `app/Http/Controllers/UserBookingController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER KLIK BOOKING TERTENTU
└─ Redirect ke /my-bookings/101 (contoh booking id 101)
└─ Backend query:
   SELECT * FROM bookings WHERE id = 101 AND user_id = 5
   SELECT * FROM progress WHERE booking_id = 101 ORDER BY created_at DESC

STEP 2: TAMPILKAN DETAIL BOOKING
Informasi booking:
├─ Booking Code: OG-20260602-ABC123
├─ Rute: Jakarta → Surabaya
├─ Tanggal: 10 Juni 2026, 08:00
├─ Penumpang: 4 orang
├─ Kelas: Bisnis
├─ Harga Total: Rp 2.000.000
└─ Status: CONFIRMED ✅

STEP 3: TAMPILKAN TIMELINE PROGRESS
Timeline tracking:
```
┌──────────────────────────────────────────────────────────────┐
│              TRACKING PERJALANAN KAPAL                       │
├──────────────────────────────────────────────────────────────┤
│                                                               │
│ 🟢 02-06-2026 08:00 - KAPAL BERANGKAT                       │
│     Lokasi: Pelabuhan Jakarta                               │
│     Deskripsi: Kapal sudah berlayar dari pelabuhan Jakarta  │
│                                                               │
│ 🟡 02-06-2026 12:00 - BERLAYAR                              │
│     Lokasi: Selat Sunda                                     │
│     Deskripsi: Kapal sedang berlayar di Selat Sunda         │
│                                                               │
│ 🟡 03-06-2026 08:00 - BERLAYAR                              │
│     Lokasi: Laut Jawa                                       │
│     Deskripsi: Kapal sedang berlayar di Laut Jawa           │
│                                                               │
│ ⚪ 03-06-2026 16:00 - SAMPAI DI TUJUAN                      │
│     Lokasi: Pelabuhan Surabaya                              │
│     Deskripsi: Kapal telah tiba di pelabuhan Surabaya       │
│                                                               │
│ ⚪ 03-06-2026 17:00 - PENUMPANG TURUN                       │
│     Lokasi: Terminal Surabaya                               │
│     Deskripsi: Penumpang sudah turun, perjalanan selesai    │
│                                                               │
└──────────────────────────────────────────────────────────────┘

WARNA TIMELINE:
🟢 HIJAU = Event terjadi hari ini atau masa lalu
🟡 KUNING = Event sedang berlangsung
⚪ PUTIH = Event akan datang (belum terjadi)
```

STEP 4: AUTO-REFRESH (Optional)
└─ Data bisa di-refresh dengan AJAX setiap 30 detik
└─ User lihat update terbaru tanpa perlu refresh manual
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/UserBookingController.php
public function show(Booking $booking)
{
    // Check user punya akses ke booking ini
    if ($booking->user_id !== auth()->id()) {
        abort(403, 'Unauthorized');
    }

    // Get all progress untuk booking ini
    $progress = $booking->progress()->latest()->get();

    return view('user.bookings.show', compact('booking', 'progress'));
}
```

### 📊 Database untuk Progress:
```sql
-- Admin create progress update
INSERT INTO progress (
    booking_id,         ← 101
    status,             ← 'Kapal Berangkat'
    description,        ← 'Kapal sudah berlayar dari Jakarta'
    location,           ← 'Pelabuhan Jakarta'
    updated_at_status,  ← '2026-06-02 08:00:00'
    created_at,
    updated_at
) VALUES (...)

-- User lihat di frontend:
SELECT * FROM progress 
WHERE booking_id = 101 
ORDER BY created_at DESC
```

---

## 6️⃣ FITUR: BATALKAN BOOKING (Cancel Booking)

### 🎯 Fungsi Utama:
Memungkinkan user membatalkan booking yang masih pending atau confirmed

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/my-bookings/{booking_id}/batal` (PATCH)
- Controller: `app/Http/Controllers/UserBookingController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: USER LIHAT BOOKING YANG BELUM SELESAI
├─ Status: PENDING atau CONFIRMED
└─ Tombol "BATALKAN" tersedia

STEP 2: USER KLIK TOMBOL "BATALKAN"
└─ Popup confirmation: "Yakin ingin batalkan booking ini?"
└─ [ Batal ] [ Yakin ]

STEP 3: USER KLIK "YAKIN"
└─ Form submit ke server dengan method PATCH
└─ URL: /my-bookings/101/batal

STEP 4: BACKEND VALIDASI
```
if (booking.status == 'pending' || booking.status == 'confirmed') {
    ✅ Boleh dibatalkan
} else if (booking.status == 'completed') {
    ❌ Tidak boleh - "Perjalanan sudah selesai"
} else if (booking.status == 'cancelled') {
    ❌ Tidak boleh - "Booking sudah dibatalkan sebelumnya"
}
```

STEP 5: UPDATE DATABASE
```
UPDATE bookings 
SET status = 'cancelled', updated_at = NOW() 
WHERE id = 101
```

STEP 6: REDIRECT & MESSAGE
└─ Redirect ke booking detail
└─ Tampilkan pesan: "✅ Booking berhasil dibatalkan"
└─ Tombol "Batalkan" menghilang
└─ Status berubah menjadi: 🔴 CANCELLED
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/UserBookingController.php
public function cancel(Booking $booking)
{
    // Check user punya akses
    if ($booking->user_id !== auth()->id()) {
        abort(403);
    }

    // Check status bisa dibatalkan
    if (!in_array($booking->status, ['pending', 'confirmed'])) {
        return redirect()->back()
                       ->with('error', 'Booking tidak bisa dibatalkan');
    }

    // Update status ke cancelled
    $booking->update(['status' => 'cancelled']);

    return redirect()->back()
                   ->with('success', 'Booking berhasil dibatalkan');
}
```

---

## 7️⃣ FITUR: ADMIN DASHBOARD

### 🎯 Fungsi Utama:
Menampilkan statistik sistem dan quick access untuk admin mengelola pengguna, booking, dan progress

### 📍 Lokasi:
- URL: `http://127.0.0.1:8000/admin/dashboard`
- File: `resources/views/admin/dashboard.blade.php`
- Controller: `app/Http/Controllers/DashboardController.php`

### 📋 Bagaimana Cara Kerja:

```
STEP 1: ADMIN LOGIN
└─ URL: /admin/login
└─ Email + password
└─ Check role == 'admin' (middleware isAdmin)

STEP 2: ADMIN BUKA DASHBOARD
└─ URL: /admin/dashboard
└─ Middleware check:
   - Is authenticated? ✅
   - Is admin? ✅
   - Show dashboard

STEP 3: SISTEM HITUNG STATISTIK
Backend query:
```
$totalUsers = User::count(); 
// SELECT COUNT(*) FROM users

$totalBookings = Booking::count();
// SELECT COUNT(*) FROM bookings

$totalRevenue = Booking::sum('price'); 
// SELECT SUM(price) FROM bookings

$pendingBookings = Booking::where('status', 'pending')->count();
// SELECT COUNT(*) FROM bookings WHERE status = 'pending'

$confirmedBookings = Booking::where('status', 'confirmed')->count();
$completedBookings = Booking::where('status', 'completed')->count();
$cancelledBookings = Booking::where('status', 'cancelled')->count();
```

STEP 4: TAMPILKAN DASHBOARD
```
┌─────────────────────────────────────────────────┐
│  👋 Selamat Datang, Admin!                     │
│  Kelola sistem pemesanan tiket kapal...        │
├─────────────────────────────────────────────────┤
│                                                 │
│  QUICK ACTIONS:                                 │
│  [ 👥 Kelola Pengguna ] [ 🎫 Kelola Booking ] │
│  [ 📊 Kelola Progress ]                       │
│                                                 │
│  STATISTIK SISTEM:                              │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐  │
│  │  Users   │ │ Bookings │ │   Revenue   │  │
│  │   145    │ │  2.340   │ │ Rp 500 juta │  │
│  └──────────┘ └──────────┘ └──────────────┘  │
│                                                 │
│  STATUS PEMESANAN:                              │
│  Pending: 45 | Confirmed: 120 | Completed: 2175
│                                                 │
└─────────────────────────────────────────────────┘
```

STEP 5: QUICK ACCESS BUTTONS
Admin bisa langsung klik tombol untuk:
├─ Kelola Pengguna (CRUD users)
├─ Kelola Pemesanan (view & approve)
└─ Kelola Progress (create & update tracking)
```

### 💻 Kode Backend:
```php
// app/Http/Controllers/DashboardController.php
public function index()
{
    // Query statistik
    $totalUsers = User::count();
    $totalBookings = Booking::count();
    $totalRevenue = Booking::sum('price');
    $pendingBookings = Booking::where('status', 'pending')->count();
    $confirmedBookings = Booking::where('status', 'confirmed')->count();
    $completedBookings = Booking::where('status', 'completed')->count();
    $cancelledBookings = Booking::where('status', 'cancelled')->count();

    // Pass ke view
    return view('admin.dashboard', [
        'totalUsers' => $totalUsers,
        'totalBookings' => $totalBookings,
        'totalRevenue' => $totalRevenue,
        'pendingBookings' => $pendingBookings,
        'confirmedBookings' => $confirmedBookings,
        'completedBookings' => $completedBookings,
        'cancelledBookings' => $cancelledBookings,
    ]);
}
```

---

## 8️⃣ FITUR: KELOLA PENGGUNA (User Management)

### 🎯 Fungsi Utama:
Admin bisa tambah, lihat, edit, dan hapus pengguna sistem

### 📍 Lokasi:
- List URL: `http://127.0.0.1:8000/admin/users`
- Create URL: `http://127.0.0.1:8000/admin/users/create`
- Edit URL: `http://127.0.0.1:8000/admin/users/{user_id}/edit`
- Controller: `app/Http/Controllers/AdminController.php`

### 📋 Bagaimana Cara Kerja:

```
OPERASI 1: LIHAT DAFTAR PENGGUNA
├─ URL: /admin/users
├─ Query: SELECT * FROM users
├─ Tampilkan tabel dengan kolom:
│  ID | Nama | Email | Role | Status | Aksi
├─ Aksi: [ Lihat ] [ Edit ] [ Hapus ]
└─ Pagination: 15 pengguna per halaman

OPERASI 2: TAMBAH PENGGUNA BARU
├─ URL: /admin/users/create
├─ Form dengan field:
│  - Nama: [_____________]
│  - Email: [_____________]
│  - Password: [_____________]
│  - Role: [user ▼] atau [admin ▼]
├─ Admin isi form
├─ Submit → INSERT ke database
├─ Database insert:
│  INSERT INTO users (name, email, password, role, created_at, updated_at)
│  VALUES ('Hendra', 'hendra@mail.com', bcrypt('password'), 'admin', NOW(), NOW())
└─ Redirect dengan pesan "✅ User berhasil ditambah"

OPERASI 3: EDIT PENGGUNA
├─ URL: /admin/users/5/edit
├─ Query: SELECT * FROM users WHERE id = 5
├─ Tampilkan form pre-filled dengan data existing
├─ Admin ubah nama/email/role
├─ Submit → UPDATE database
├─ Database update:
│  UPDATE users SET name='Hendra Baru', email='hendra_baru@mail.com'
│  WHERE id = 5
└─ Redirect dengan pesan "✅ User berhasil diupdate"

OPERASI 4: HAPUS PENGGUNA
├─ URL: /admin/users/5/delete (POST)
├─ Confirmation popup: "Yakin hapus user ini?"
├─ DELETE juga cascade:
│  - DELETE FROM bookings WHERE user_id = 5
│  - DELETE FROM progress WHERE booking_id IN (...)
├─ Database delete:
│  DELETE FROM users WHERE id = 5
└─ Redirect dengan pesan "✅ User berhasil dihapus"
```

### 💻 Contoh Kode:
```php
// Create user baru
public function storeUser(Request $request)
{
    $validated = $request->validate([
        'name' => 'required|string',
        'email' => 'required|email|unique:users',
        'password' => 'required|min:8',
        'role' => 'required|in:user,admin',
    ]);

    User::create([
        'name' => $validated['name'],
        'email' => $validated['email'],
        'password' => bcrypt($validated['password']),
        'role' => $validated['role'],
    ]);

    return redirect('/admin/users')->with('success', 'User berhasil ditambah');
}
```

---

## 9️⃣ FITUR: KELOLA PEMESANAN (Booking Management)

### 🎯 Fungsi Utama:
Admin bisa lihat, edit status, dan hapus booking

### 📍 Lokasi:
- List URL: `http://127.0.0.1:8000/admin/bookings`
- Edit URL: `http://127.0.0.1:8000/admin/bookings/{booking_id}/edit`
- Controller: `app/Http/Controllers/AdminController.php`

### 📋 Bagaimana Cara Kerja:

```
OPERASI 1: LIHAT SEMUA BOOKING
├─ URL: /admin/bookings
├─ Query: SELECT * FROM bookings
├─ Tampilkan tabel:
│  Booking Code | User | Rute | Status | Tanggal | Aksi
│  OG-20260602-ABC | Budi | Jkt→Sby | PENDING | 10-06 | [ Edit ]
│  OG-20260601-XYZ | Andi | Sby→Jkt | CONFIRM | 5-06  | [ Edit ]
└─ Filter by status (Pending, Confirmed, Completed, Cancelled)

OPERASI 2: EDIT STATUS BOOKING
├─ URL: /admin/bookings/101/edit
├─ Query: SELECT * FROM bookings WHERE id = 101
├─ Form dengan dropdown:
│  Status sekarang: PENDING
│  Ubah ke: [ Pending ▼ ]
│           [ Confirmed ]
│           [ Completed ]
│           [ Cancelled ]
├─ Admin pilih "Confirmed"
├─ Submit → UPDATE database
│  UPDATE bookings SET status = 'confirmed' WHERE id = 101
└─ Redirect dengan pesan "✅ Status booking berhasil diupdate"

OPERASI 3: LIHAT DETAIL BOOKING
├─ URL: /admin/bookings/101
├─ Tampilkan:
│  ├─ Informasi booking lengkap
│  ├─ Data penumpang (nama, jumlah)
│  ├─ Harga breakdown
│  ├─ Riwayat progress
│  └─ Tombol untuk edit atau hapus
└─ Admin bisa lihat journey lengkap

OPERASI 4: HAPUS BOOKING
├─ URL: /admin/bookings/101 (DELETE)
├─ DELETE juga cascade:
│  - DELETE FROM progress WHERE booking_id = 101
├─ Database delete:
│  DELETE FROM bookings WHERE id = 101
└─ Redirect dengan pesan "✅ Booking berhasil dihapus"
```

---

## 🔟 FITUR: KELOLA PROGRESS (Progress Management)

### 🎯 Fungsi Utama:
Admin bisa membuat dan update status tracking perjalanan kapal untuk setiap booking

### 📍 Lokasi:
- List URL: `http://127.0.0.1:8000/admin/progress`
- Create URL: `http://127.0.0.1:8000/admin/progress/create`
- Edit URL: `http://127.0.0.1:8000/admin/progress/{progress_id}/edit`
- Controller: `app/Http/Controllers/AdminController.php`

### 📋 Bagaimana Cara Kerja:

```
OPERASI 1: LIHAT PROGRESS TRACKING
├─ URL: /admin/progress
├─ Query: SELECT * FROM progress ORDER BY created_at DESC
├─ Tampilkan timeline semua update:
│  Booking | Status | Lokasi | Waktu | Deskripsi | Aksi
│  OG-ABC | Berangkat | Jakarta | 10-06 08:00 | Kapal berlayar | [ Edit ]
│  OG-ABC | Berlayar | Laut Jawa | 10-06 12:00 | Berlayar lancar | [ Edit ]
└─ Pagination: latest 20 progress per halaman

OPERASI 2: TAMBAH PROGRESS BARU
├─ URL: /admin/progress/create
├─ Form dengan field:
│  ├─ Pilih Booking: [ OG-20260602-ABC ▼ ]
│  ├─ Status: [ Berangkat / Berlayar / Sampai / Penumpang Turun ]
│  ├─ Lokasi: [ Jakarta ]
│  ├─ Deskripsi: [ Kapal sudah berlayar dari Jakarta ]
│  └─ Waktu: [ auto = current timestamp ]
├─ Admin isi form
├─ Submit → INSERT ke database:
│  INSERT INTO progress (
│    booking_id = 101,
│    status = 'Berangkat',
│    location = 'Jakarta',
│    description = 'Kapal sudah berlayar dari Jakarta',
│    updated_at_status = NOW(),
│    created_at = NOW(),
│    updated_at = NOW()
│  ) VALUES (...)
├─ User otomatis lihat update di timeline booking mereka
└─ Redirect dengan pesan "✅ Progress berhasil ditambah"

OPERASI 3: EDIT PROGRESS
├─ URL: /admin/progress/5/edit
├─ Query: SELECT * FROM progress WHERE id = 5
├─ Form pre-filled dengan data existing
├─ Admin ubah status, lokasi, atau deskripsi
├─ Submit → UPDATE database:
│  UPDATE progress 
│  SET status='Berlayar', location='Laut Jawa'
│  WHERE id = 5
└─ Redirect dengan pesan "✅ Progress berhasil diupdate"

OPERASI 4: HAPUS PROGRESS
├─ URL: /admin/progress/5 (DELETE)
├─ Confirmation: "Yakin hapus progress ini?"
├─ Database delete:
│  DELETE FROM progress WHERE id = 5
└─ Redirect dengan pesan "✅ Progress berhasil dihapus"

REAL-TIME EFFECT:
└─ Saat admin create/update progress:
   1. Data simpan di database progress table
   2. User booking buka detail booking
   3. Otomatis lihat timeline update terbaru
   4. (Optional) dengan AJAX: refresh every 30 detik
```

### 📊 Contoh Timeline:
```
TIMELINE TRACKING KAPAL (Real-Time Update)

Booking: OG-20260602-ABC (Jakarta → Surabaya)
Admin update progress:

11:00 - Admin create: "Kapal Berangkat"
        Location: Pelabuhan Jakarta
        → User lihat di dashboard: 🟢 BERANGKAT

14:30 - Admin create: "Kapal Berlayar"
        Location: Selat Sunda
        → User lihat: 🟡 BERLAYAR

Next day 08:00 - Admin create: "Kapal Berlayar"
                 Location: Laut Jawa
                 → User lihat: 🟡 BERLAYAR

Next day 16:00 - Admin create: "Kapal Tiba"
                 Location: Pelabuhan Surabaya
                 → User lihat: 🟢 TIBA

Next day 17:00 - Admin create: "Penumpang Turun"
                 Location: Terminal Surabaya
                 → User lihat: ✓ SELESAI

Result: Timeline lengkap terbentuk dari multiple progress entries
```

---

## 🔐 FITUR: SECURITY & AUTHENTICATION

### 🎯 Fungsi Utama:
Melindungi data dan memastikan hanya user yang authorized yang bisa akses resources

### 📋 Bagaimana Cara Kerja:

```
LEVEL 1: PASSWORD HASHING
├─ User input password: "Rahasia123"
├─ Sistem hash dengan Bcrypt:
│  bcrypt('Rahasia123') = '$2y$12$XYZ...abc...'
├─ Disimpan di database (bukan plain text)
├─ Saat login:
│  bcrypt('Rahasia123') == '$2y$12$XYZ...' → ✅ Match
│  bcrypt('SalahPassword') == '$2y$12$XYZ...' → ❌ No Match
└─ Password tidak bisa di-reverse (one-way encryption)

LEVEL 2: SESSION MANAGEMENT
├─ User login berhasil
├─ Server create session:
│  session_id = 'abcd1234efgh5678'
│  user_id = 5
│  user_role = 'user'
│  login_time = 2026-06-02 10:30:00
├─ Session disimpan di server
├─ Browser kirim cookie: PHPSESSID=abcd1234efgh5678
├─ Setiap request, browser kirim session_id di cookie
├─ Server check: session valid? user login?
├─ Session timeout = 120 menit
├─ Jika timeout → session destroyed → user harus login lagi
└─ Logout → session destroyed manual

LEVEL 3: MIDDLEWARE AUTHENTICATION
├─ Protected route: /my-bookings
├─ Middleware: auth
├─ Check: Is user authenticated?
│  - Ada session? ✅
│  - Session valid? ✅
│  - User exist di database? ✅
├─ Jika OK → lanjut ke controller
├─ Jika tidak → redirect ke login
└─ Public route tidak perlu middleware

LEVEL 4: MIDDLEWARE AUTHORIZATION (RBAC)
├─ Protected route: /admin/dashboard
├─ Middleware: auth, isAdmin
├─ Check 1: Is user authenticated? (auth middleware)
├─ Check 2: Is user role == 'admin'? (isAdmin middleware)
├─ Jika OK → show admin dashboard
├─ Jika tidak → 403 Forbidden
└─ User regular tidak bisa akses admin routes

LEVEL 5: CSRF TOKEN PROTECTION
├─ Setiap form POST/PUT/DELETE perlu CSRF token
├─ Token di-generate per session
├─ Form include: <input type="hidden" name="_token" value="...">
├─ Submit form:
│  - Browser kirim form data + token
│  - Server validate token
│  - Token valid? ✅ → proses form
│  - Token tidak valid? ❌ → reject (419 error)
└─ Prevent cross-site request forgery

LEVEL 6: SQL INJECTION PREVENTION
├─ Wrong way (vulnerable):
│  $sql = "SELECT * FROM users WHERE email = '" . $email . "'";
│  → Attacker bisa input: admin' OR '1'='1
│  → Query jadi: SELECT * FROM users WHERE email = 'admin' OR '1'='1'
│  → Ambil semua users!
│
├─ Right way (Eloquent ORM):
│  User::where('email', $email)->get()
│  → Parameter di-escape otomatis
│  → Tidak bisa injection
│
└─ Oceango gunakan Eloquent → safe dari SQL injection

LEVEL 7: INPUT VALIDATION
├─ User input di form
├─ Server validate:
│  - Email format valid? (format@email.com)
│  - Password minimal 8 karakter?
│  - Booking tanggal tidak di masa lalu?
│  - Number fields berisi number?
├─ Jika tidak valid → show error message
├─ Frontend validation (untuk UX)
├─ Backend validation (untuk security)
└─ Backend validation wajib (frontend bisa dibypass)
```

---

## 📝 RINGKASAN FITUR:

```
FITUR USER (Pelanggan):
1. ✅ Register         → Buat akun baru
2. ✅ Login            → Masuk dengan email + password
3. ✅ Dashboard        → Lihat statistik booking saya
4. ✅ Pesan Tiket      → Membuat booking baru
5. ✅ Lihat Riwayat    → Daftar booking saya
6. ✅ Tracking Status  → Lihat progress perjalanan
7. ✅ Batalkan Booking → Membatalkan booking
8. ✅ Logout           → Keluar

FITUR ADMIN (Pengelola):
1. ✅ Admin Login      → Login ke admin panel
2. ✅ Dashboard        → Statistik sistem
3. ✅ Kelola Pengguna  → CRUD users
4. ✅ Kelola Booking   → View & update status
5. ✅ Kelola Progress  → Create & update tracking
6. ✅ View Reports     → Lihat statistik
7. ✅ Admin Logout     → Keluar

SECURITY:
✅ Password hashing (Bcrypt)
✅ Session management (120 min timeout)
✅ Middleware authentication
✅ Role-based authorization
✅ CSRF token protection
✅ SQL injection prevention
✅ Input validation
✅ Error handling
```

Semua fitur sudah terjelaskan lengkap dengan fungsi, cara kerja, dan contoh! 🎉
