# Category Management Module Usage Instructions

> The `feat/admin-sub/global-category-management` branch introduces a powerful, centralized Global Category system. Instead of building separate category tables for every feature (Blogs, Products, etc.), this branch provides a single, unified structure for managing Parent and Sub-categories scoped dynamically by module type.

---

## Table of Contents

1. [Module Overview](#1-module-overview)
2. [What You Inherit](#2-what-you-inherit)
3. [Deep Dive: Features & Functionality](#3-deep-dive-features--functionality)
4. [Integration Guide: Using Categories in Other Modules](#4-integration-guide-using-categories-in-other-modules)
5. [File Paths & Architecture](#5-file-paths--architecture)
6. [Step-by-Step Usage Guide](#6-step-by-step-usage-guide)

---

## 1. Module Overview

This branch establishes the core Category Management area in the Admin Portal. It allows administrators to create hierarchies (Parent Categories and Sub-Categories), upload category images, assign descriptions, and map these categories specifically to different areas of the application (e.g., "Blog Categories" vs "Product Categories"). 

---

## 2. What You Inherit

By merging with the **Base** and **Admin** branches, this feature inherits:
- **UI Components:** Reusable `<x-common.*>` and `<x-forms.*>` Blade components, maintaining a consistent aesthetic.
- **Admin Security:** Protected by the `auth:admin` middleware.
- **AJAX Modal Architecture:** A completely modal-driven workflow for Creating, Editing, and Deleting categories without leaving the data table view.

---

## 3. Deep Dive: Features & Functionality

- **Centralized Architecture:** 
  Utilizes a single `categories` table and a `categorizables` pivot table. This prevents database bloat by avoiding multiple tables like `blog_categories`, `product_categories`, etc.
- **Type Scoping:** 
  Categories belong to a specific "Type" (e.g., Blog). When managing categories, you can filter by these types.
- **Sub-Category Management:**
  Clicking on the "Sub categories" count in the main table navigates to a nested view to manage children belonging specifically to that parent category.
- **Image Uploads:** 
  Categories support 1:1 square image uploads (PNG/JPG) up to 5MB for visual categorization on the frontend.
- **Smart Slugs:** 
  Slugs are unique *within the same type and parent*, not globally, preventing unnecessary suffixing across different modules.

---

## 4. Integration Guide: Using Categories in Other Modules

When you build a new module (like "Products" or "Portfolio") and want to assign categories (or sub-categories) to those items, follow these steps:

### Sub-Categories Briefing
Sub-categories operate under the exact same data model as parent categories—they simply possess a `parent_id`. When integrating with other modules, they are treated identically. The `HasCategory` trait allows assigning either a parent category or a sub-category directly to your model. The frontend components (like `<x-category-select>`) handle displaying the hierarchy seamlessly.

### Step 1: Prepare the Eloquent Model
Add the `HasCategory` trait to your new model and define the `$categoryModule` property. This registers the model with the `CategoryRegistry` and enables automatic syncing.
```php
namespace App\Models;

use App\Traits\HasCategory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    use HasCategory;

    // This registers the model with the CategoryRegistry
    protected string $categoryModule = 'Blog'; 
}
```

### Step 2: Use the Blade Component in your Form
In your module's create/edit form, render a dropdown that fetches only the categories meant for your module using the `<x-category-select>` component. 
*Note: To leverage the trait's automatic syncing, name your input field `{Module}_category_id` (e.g., `Blog_category_id`):*
```html
<x-category-select 
    name="Blog_category_id" 
    :type="\App\Models\Blog::class" 
    :selected="isset($blog) ? $blog->categories->pluck('id')->toArray() : []" 
/>
```

### Step 3: Automatic Saving via Trait
Because you included the `HasCategory` trait and named your input `Blog_category_id` (or similar), **you do not need to manually save the category in your controller**. 
The trait listens for the `saved` Eloquent event on your model and automatically syncs the category from the HTTP request into the `categorizables` pivot table.

If you ever need to manually assign multiple categories (or bypass the automatic request syncing), you can do so safely via:
```php
// Safe sync: ignores category IDs that don't belong to this model type
$blog->syncCategories([$categoryId1, $categoryId2]);
```

---

## 5. File Paths & Architecture

Here are the key structural areas introduced:

### Core Architecture (`app/Support/`, `app/Traits/`)
- **`CategoryRegistry.php`**: The engine that tracks which Eloquent Models have opted into the category system.
- **`HasCategory.php`**: The trait that sets up the polymorphic relationships (`morphToMany`) and boot hooks.

### Controllers & Services (`app/Http/Controllers/Admin/Category/`)
- **`ParentCategoryController.php`** & **`SubCategoryController.php`**: Handle the AJAX datatables and modal submissions.
- **`CategoryService.php`** & **`SubCategoryService.php`**: Handle DB transactions, image uploads, and registry validation.

### Database (`database/migrations/`)
- **`create_categories_table.php`**: The main table housing `name`, `slug`, `type`, and `parent_id`.
- **`create_categorizables_table.php`**: The polymorphic pivot table connecting a `Category` to any other Eloquent model.

### Views (`resources/views/pages/admin/categories/`)
- Contains `index`, `form-modal`, and nested `sub-category/` views strictly following the Alpine.js modal pattern.

---

## 6. Step-by-Step Usage Guide

### 1. Database Setup
Ensure your database contains the new `categories` and `categorizables` tables.
```bash
php artisan migrate
```

### 2. Accessing the Module
- Log into the Admin Portal (`/behindthescreen`).
- In the sidebar navigation, locate and click on **Categories**.

### 3. Managing Categories
- **Creating:** Click "Add New Category". Select the "Type" (e.g., Blog), provide a Name, Description, and an Image.
- **Sub-Categories:** On the main table, click the "Sub Categories" column button for a specific row to manage its children.
- **Filtering:** Use the top filter bar to view categories belonging only to a specific module type.
- **Deleting:** Deleting a parent category will naturally affect its sub-categories. Implementations in your other modules (like `countUsingCategory`) will warn admins if a category is currently assigned to active records before deletion.
