# View Composers

Terdapat 3 View Composers dalam `app/View/Composers/`:

| Composer | View | Tujuan | Registered? |
|----------|------|--------|-------------|
| `FrontendUserMenuComposer` | `frontend.layouts.partials.sidebar` | Sidebar user login | ✅ Ya |
| `PublicMenuComposer` | `home.layouts.master` | Navbar public site | ✅ Ya |
| `MenuComposer` | (legacy) | Navbar landing page | ❌ Tidak |

---

## 1. FrontendUserMenuComposer

**File:** `app/View/Composers/FrontendUserMenuComposer.php`
**View:** `frontend.layouts.partials.sidebar`

### Tujuan

Menghasilkan menu sidebar untuk frontend user yang sudah login. Menu diambil dari `RoleMapping` berdasarkan role Spatie user, difilter oleh `category = 'sidebar'`.

### Cara Kerja

1. Ambil user dari `auth()->guard('user')`
2. Dapatkan role names via Spatie `getRoleNames()`
3. Cari `site_id` default dari `frontend_sites`
4. Query `RoleMapping` dengan filter:
   - `role_code IN (user's roles)`
   - `category = 'sidebar'`
   - `status = true`
   - `site_id = default_site` **ATAU** `site_id = 0` (global)
5. Filter hanya menu dengan `menu_status = true`
6. Build tree structure berdasarkan `parent_id` → `menu_id` hierarchy
7. Setiap node ada flag `active` — true jika URL node atau URL mana-mana child match request semasa

### Data Dihantar ke View

```php
$menuTree = [
    [
        'name' => 'Article',
        'icon' => 'fa-file',
        'url' => 'http://.../articles',
        'category' => 'sidebar',
        'active' => false,
        'children' => [
            [
                'name' => 'Gallery',
                'icon' => null,
                'url' => 'http://.../gallery',
                'category' => 'sidebar',
                'active' => true,
                'children' => [],
            ],
        ],
    ],
];
```

### View (sidebar.blade.php)

**`sidebar.blade.php`:**
```blade
@forelse($menuTree as $menu)
    @include('frontend.layouts.partials.sidebar', ['menu' => $menu, 'level' => 0])
@empty
    <p>No menu items available.</p>
@endforelse
```

**Sidebar rendering:**
- Ada `x-data="{ open: ... }"` untuk accordion toggle
- Anak panah chevron (`menu-item-arrow`) — active/inactive
- Klik parent → toggle show/hide children via `block`/`hidden`
- Children guna `x-show` + `x-collapse` (animasi smooth)

---

## 2. PublicMenuComposer

**File:** `app/View/Composers/PublicMenuComposer.php`
**View:** `home.layouts.master`

### Tujuan

Menghasilkan navbar untuk public site (pengunjung tak login). Menggunakan `RoleMapping` yang difilter oleh `role_code` dan `category_id`.

### Cara Kerja

1. Ambil `site_id` default
2. Query `RoleMapping`:
   - `role_code = $this->roleCode` (default: `'public'`)
   - `status = true`
   - `site_id = default_site` **ATAU** `site_id = 0`
   - `category_id = main-navbar category` (default)
3. Jika ada data → map ke `$navItems` (array of `menu_name`, `menu_link`)
4. Jika tiada data → fallback ke semua `Menu` dari DB + login links

### Constructor

```php
public function __construct(
    string $roleCode = 'public',
    ?string $categoryName = 'main-navbar'
)
```

### Data Dihantar ke View

```php
$navItems = [
    ['menu_name' => 'Article', 'menu_link' => 'http://.../articles'],
    ['menu_name' => 'User Login', 'menu_link' => 'http://.../login'],
];
```

### Fallback

```php
// Ambil semua menu aktif
Menu::where('menu_status', true)->get()

// + hardcoded links
['menu_name' => 'User Login', 'menu_link' => route('user.login')]
['menu_name' => 'Admin Login', 'menu_link' => route('admin.login'), 'is_admin' => true]
```

---

## 3. MenuComposer (Legacy)

**File:** `app/View/Composers/MenuComposer.php`
**Status:** ❌ **Tidak didaftarkan** di mana-mana service provider. Mungkin legacy dari versi lama.

### Tujuan (Asal)

Menghasilkan navbar untuk landing page (bukan CMS site). Ambil semua menu terus dari `frontend_menu` table, cache 1 jam.

### Cara Kerja

1. Query terus dari `Menu` model (tanpa `RoleMapping`)
2. Hardcoded items: Home (`#hero`), Features (`#features`), About (`#about`)
3. Dynamic items dari DB dengan parent-child hierarchy
4. Login links: User Login + Admin Login

Data dihantar sebagai `$navItems` ke view.

**Nota:** `PublicMenuComposer` adalah pengganti yang lebih baik kerana ia menggunakan `RoleMapping` untuk kawalan akses yang lebih granular.

---

## 4. Register Composer

Semua pendaftaran di `app/Providers/AppServiceProvider.php`:

```php
// Public site navbar — guna role 'public', category_id 'main-navbar'
View::composer('home.layouts.master', PublicMenuComposer::class);

// Frontend user sidebar — filter role user, category='sidebar', site default/global
View::composer('frontend.layouts.partials.sidebar', FrontendUserMenuComposer::class);
```

### Custom Instance

Nak guna `PublicMenuComposer` dengan parameter berbeza (contohnya role `guest`, set `MAIN`):

```php
View::composer('home.layouts.master', function ($view) {
    $c = new PublicMenuComposer('guest', 'MAIN');
    $c->compose($view);
});
```

---

## Ringkasan Data Flow

```
User Login → FrontendUserMenuComposer → $menuTree → sidebar.blade.php

Public Visit → PublicMenuComposer → $navItems → home.layouts.master (navbar)

Legacy       → MenuComposer       → $navItems → (tidak digunakan lagi)
```
