# How to Send app_name and app_module to MediaController.store()

## Complete Flow Explanation

The `app_name` and `app_module` are automatically sent through the following flow:

### 1️⃣ FormField Component (Frontend)
```tsx
<FormField
    type="media-picker"
    name="media_id"
    label="Media"
    placeholder="Select blog media"
    app_name="website"           // ← Passed here
    app_module="blog"             // ← Passed here
/>
```

### 2️⃣ FormField.tsx (Component Router)
In `/resources/js/components/form/FormField.tsx` at line ~310:

```tsx
case 'media-picker':
    return (
        <MediaPickerField
            name={props.name}
            disabled={props.disabled}
            className={props.className}
            placeholder={props.placeholder}
            multiple={props.multiple}
            initialMedia={props.initialMedia}
            app_name={(props as any).app_name}        // ← Forwarded here
            app_module={(props as any).app_module}    // ← Forwarded here
        />
    );
```

### 3️⃣ MediaPickerField.tsx (Field Component)
In `/resources/js/components/form/fields/MediaPickerField.tsx`:

```tsx
interface MediaPickerFieldProps {
    name: string;
    disabled?: boolean;
    className?: string;
    placeholder?: string;
    multiple?: boolean;
    initialMedia?: GalleryItem | GalleryItem[];
    app_name?: string;            // ← Received here
    app_module?: string;          // ← Received here
    onChange?: (media: GalleryItem | GalleryItem[] | null) => void;
}

export const MediaPickerField = ({
    name,
    disabled,
    className,
    placeholder = 'Select Media',
    multiple = false,
    initialMedia,
    app_name,                     // ← Extracted here
    app_module,                   // ← Extracted here
    onChange,
}: MediaPickerFieldProps) => {
    return (
        <MediaPicker
            onSelect={handleSelect}
            onMultiSelect={handleMultiSelect}
            enableMultiSelect={multiple}
            defaultValue={multiple ? selectedMedia : selectedMedia[0]}
            app_name={app_name}       // ← Forwarded here
            app_module={app_module}   // ← Forwarded here
        />
    );
};
```

### 4️⃣ MediaPicker.tsx (Dialog Component)
In `/Website/Gallery/resources/assets/js/components/MediaPicker.tsx`:

```tsx
interface MediaPickerProps {
    onSelect: (item: MediaItem) => void;
    trigger?: React.ReactNode;
    open?: boolean;
    onOpenChange?: (open: boolean) => void;
    enableMultiSelect?: boolean;
    onMultiSelect?: (items: MediaItem[]) => void;
    defaultValue?: MediaItem | MediaItem[];
    app_name?: string;             // ← Received here
    app_module?: string;           // ← Received here
}

export function MediaPicker({
    onSelect,
    trigger,
    open: controlledOpen,
    onOpenChange: controlledOpenChange,
    enableMultiSelect = false,
    onMultiSelect,
    defaultValue,
    app_name,                      // ← Extracted here
    app_module,                    // ← Extracted here
}: MediaPickerProps) {
    
    const handleUpload = async (files: File[]) => {
        setLoading(true);
        const formData = new FormData();
        files.forEach((file) => formData.append('file', file));
        
        // ✅ HERE: Append app_name and app_module to FormData
        if (app_name) formData.append('app_name', app_name);
        if (app_module) formData.append('app_module', app_module);

        try {
            await axios.post(route('media.store'), formData, {
                headers: { 'Content-Type': 'multipart/form-data' },
            });
            fetchData();
        } catch (error) {
            console.error('Upload failed', error);
        }
        setLoading(false);
    };
}
```

### 5️⃣ MediaController.store() (Backend)
In `/app/Http/Controllers/MediaController.php`:

```php
public function store(Request $request)
{
    $request->validate([
        'file' => 'required|file|max:20480',
        'app_name' => 'nullable|string|max:255',
        'app_module' => 'nullable|string|max:255',
    ]);

    // ✅ HERE: Access the values from request
    $app_name = $request->input('app_name', 'platform');  // Default: 'platform'
    $module = $request->input('app_module', 'media');     // Default: 'media'

    // Build the storage path
    $fullPath = $directory.'/'.$tenant_slug.'/'.$app_name.'/'.$module;
    
    // ... rest of upload logic
}
```

---

## Usage in Blog Module Example

### 1. In Blog Create Form (Blog/Create.tsx)
```tsx
<FormField
    type="media-picker"
    name="media_id"
    label="Blog Featured Image"
    placeholder="Select blog media"
    app_name="website"      // ← App name
    app_module="blog"       // ← Module name
/>
```

### 2. Storage Path Generated
```
product-slug/tenant-slug/website/blog/image.jpg
```

### 3. In Blog Edit Form (Blog/Edit.tsx)
```tsx
<FormField
    type="media-picker"
    name="media_id"
    label="Blog Featured Image"
    placeholder="Select blog media"
    app_name="website"
    app_module="blog"
    initialMedia={blog?.media}  // Pre-select existing media
/>
```

---

## Available Default Paths

### Website Module
```
blog:         website/blog/{file}
page:         website/page/{file}
gallery:      website/gallery/{file}
testimonial:  website/testimonial/{file}
achievement:  website/achievement/{file}
notice:       website/notice/{file}
```

### Academic Module
```
admission:    academic/admission/{file}
curriculum:  academic/curriculum/{file}
result:      academic/result/{file}
routine:     academic/routine/{file}
syllabus:    academic/syllabus/{file}
calendar:    academic/calendar/{file}
```

### E-Commerce Module
```
blog:         ecommerce/blog/{file}
product:     ecommerce/product/{file}
```

---

## Key Points

✅ **No manual passing required** - The component handles it automatically  
✅ **Default values** - `app_name` defaults to 'platform' if not provided  
✅ **Module path** - `app_module` defaults to 'media' if not provided  
✅ **Storage structure** - Creates organized directory: `{app}/{tenant}/{app_name}/{module}/{file}`  
✅ **FormData** - Automatically appended to multipart form submission  
✅ **Controller access** - Use `$request->input('app_name')` and `$request->input('app_module')`  

---

## Example: Custom Usage

```tsx
// In any component
<FormField
    type="media-picker"
    name="custom_media"
    label="Custom Media"
    placeholder="Select media"
    app_name="custom_app"    // Custom app name
    app_module="custom_mod"  // Custom module name
/>

// Will store at:
// product-slug/tenant-slug/custom_app/custom_mod/file.ext
```

The entire flow is **automatic** - just add the `app_name` and `app_module` props to your FormField component! 🚀
