2.1 KiB

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

<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

<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

GET /api/media/public?page=1&limit=24&search=climate&sort=recent&category=testimonials

Response:

{
  "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
}