107 lines
2.1 KiB
Markdown

# Media Gallery Page
## Overview
**File Path:** `admin/src/pages/public/MediaGalleryPage.tsx` (195 lines)
**Route:** `/media` (with optional `?category=X` query param)
**Role Requirements:** Public access
**Purpose:** Public-facing video gallery displaying shared media content with search, sort, category filtering, and pagination.
**Key Features:**
- Search input with 300ms debounce
- Sort dropdown (Recent, Popular, Most Viewed)
- Responsive grid (xs=1, sm=2, md=3, lg=4 columns)
- PublicVideoCard component
- Pagination (24 videos per page)
- Category filter from URL params
- Dark theme consistency
**Layout:** Uses `MediaPublicLayout` (specialized public layout for media)
---
## Features
### 1. Search Bar
```tsx
<Input.Search
placeholder="Search videos..."
size="large"
onChange={(e) => {
clearTimeout(searchDebounce);
searchDebounce = setTimeout(() => {
setSearchTerm(e.target.value);
setPage(1);
}, 300);
}}
style={{ maxWidth: 500 }}
/>
```
### 2. Sort Dropdown
Options:
- **Recent**: `createdAt DESC`
- **Popular**: `reactionCount DESC`
- **Most Viewed**: `viewCount DESC`
### 3. Video Grid
```tsx
<Row gutter={[16, 16]}>
{videos.map(video => (
<Col xs={24} sm={12} md={8} lg={6} key={video.id}>
<PublicVideoCard video={video} />
</Col>
))}
</Row>
```
### 4. Category Filter
URL-based filtering:
- `/media` - All categories
- `/media?category=testimonials` - Testimonials only
- `/media?category=events` - Events only
---
## API Integration
```http
GET /api/media/public?page=1&limit=24&search=climate&sort=recent&category=testimonials
```
Response:
```json
{
"videos": [
{
"id": "vid123",
"title": "Climate Rally Highlights",
"thumbnailUrl": "/media/thumbnails/vid123.jpg",
"duration": 245,
"viewCount": 1523,
"upvotes": 87,
"category": "events"
}
],
"total": 156,
"page": 1,
"limit": 24
}
```
---
## Related Documentation
- [Media Viewer Page](./media-viewer-page.md)
- [Library Management](../admin/media/library-page.md)
- [Shared Media Admin](../admin/media/shared-media-page.md)