Reusable React component for managing a media gallery — supports image and video upload, drag-to-reorder, and deletion with an optional modal wrapper. ## Key Components ### `MediaItem` (interface) Data shape for a single gallery entry: | Field | Type | Notes | |---|---|---| | `id` | `string \| number` | Optional; omitted for new items | | `media_type` | `'image' \| 'video' \| 'screenshot' \| 'demo'` | Controls render path | | `media_url` | `string` | Resolved URL after upload | | `title` | `string` | Displayed below the thumbnail | | `display_order` | `number` | Updated automatically on reorder | | `_uploading` | `boolean` | Optimistic upload state flag | ### `MediaGalleryManager` (component) | Prop | Type | Default | Description | |---|---|---|---| | `media` | `MediaItem[]` | — | Controlled list of media items | | `onChange` | `(media: MediaItem[]) => void` | — | Called on add, delete, or reorder | | `onUpload` | `(file, mediaType) => Promise` | — | Async upload handler; returns resolved URL | | `isUploading` | `boolean` | `false` | Shows spinner and disables controls | | `showInModal` | `boolean` | `false` | Reserved for modal rendering mode | | `modalTitle` | `string` | `'Media Gallery'` | Title when rendered in a modal | | `className` | `string` | `''` | Additional wrapper classes | **Internal behaviors:** - `handleFileSelect` — detects MIME type, calls `onUpload`, appends new `MediaItem` - `handleDeleteMedia` — filters item by index, updates order - `handleDragStart / handleDrop` — HTML5 drag-and-drop reorder; recalculates `display_order` on drop ## Usage Example ```typescript import { MediaGalleryManager, MediaItem } from './media-gallery-manager'; const [gallery, setGallery] = useState([]); async function uploadToStorage(file: File, mediaType: 'image' | 'video') { const formData = new FormData(); formData.append('file', file); const res = await fetch('/api/upload', { method: 'POST', body: formData }); const { url } = await res.json(); return url; } ``` ## Notes - Videos (`video`, `demo`) render via the internal `