Files
MyClub/DOCS/YOUTUBE_CLUB_VIDEOS_INTEGRATION.md
T
Tomáš Dvořák 12cba639b9 upload
2025-10-16 13:32:05 +02:00

14 KiB

YouTube Club Videos Integration - Activity Events

🎯 Enhancement Summary

The YouTube video selector in Admin → Aktivity now has TWO options:

  1. Select from club's YouTube channel (new!)
  2. Manual URL input (existing)

New Features

Dual Tab Interface

┌─ YouTube Video (volitelné) ──────────────────┐
│                                               │
│  [Z kanálu klubu (15)] [Vlastní odkaz]      │  ← Tabs
│  ─────────────────────────────────────────── │
│                                               │
│  Tab 1: Club Videos (scrollable gallery)     │
│  or                                           │
│  Tab 2: Custom URL input                     │
│                                               │
└───────────────────────────────────────────────┘

Tab 1: From Club Channel

Shows your club's YouTube videos:

┌─────────────────────────────────────────────┐
│ [Thumbnail]  Video Title                   │
│ 60x60        Published • Views  [Vybráno]  │
├─────────────────────────────────────────────┤
│ [Thumbnail]  Another Video                 │
│ 60x60        3 days ago • 1.2K views       │
├─────────────────────────────────────────────┤
│ [Thumbnail]  Match Highlights              │
│ 60x60        1 week ago • 5.4K views       │
└─────────────────────────────────────────────┘
        Scrollable list (max 300px height)

Features:

  • Loads videos from club's YouTube channel automatically
  • Shows 20 most recent videos
  • Displays thumbnail, title, date, views
  • Click any video to select it
  • Visual feedback (red border when selected)
  • Shows "Vybráno" badge on selected video
  • Toast notification when selected

Tab 2: Custom URL

Manual URL input (for any YouTube video):

┌──────────────────────────────────────────┐
│ https://www.youtube.com/watch?v=...     │
└──────────────────────────────────────────┘
Vložte odkaz na jakékoliv YouTube video

Use for:

  • Videos from other channels
  • Unlisted videos
  • Private videos
  • Any YouTube content

🎬 How It Works

Admin Workflow

  1. Click "YouTube Video" section
  2. Default tab: "Z kanálu klubu" opens
  3. Scroll through your club's videos
  4. Click video thumbnail/title to select
  5. Toast notification: "Video vybráno"
  6. Red border appears around selected video
  7. Badge shows "Video nastaveno"
  8. Save event

Example:

Admin sees:
- "Match Highlights vs Sparta" (thumbnail)
- "Training Session March 2024" (thumbnail)
- "Youth Tournament 2024" (thumbnail)

Clicks "Match Highlights vs Sparta"
→ Video selected!
→ URL: https://www.youtube.com/watch?v=abc123
→ Saved to event

Option B: Custom URL

  1. Click "Vlastní odkaz" tab
  2. Paste any YouTube URL
  3. Save event

Supported formats:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://www.youtube.com/embed/VIDEO_ID

🎨 Visual Design

Tab Buttons

"Z kanálu klubu" (active)

[🎬 Z kanálu klubu (15)]  ← Red solid button

"Vlastní odkaz" (inactive)

[🔗 Vlastní odkaz]  ← Gray outline button

Video List Item

Unselected:

┌─────────────────────────────────────┐
│ [Thumb]  Video Title               │
│          Published • Views          │
└─────────────────────────────────────┘
Gray border, white background
Hover: Red border, red background

Selected:

┌═════════════════════════════════════┐ ← Red border
║ [Thumb]  Video Title   [Vybráno]  ║ ← Red background
║          Published • Views          ║
└═════════════════════════════════════┘

Status Indicator

When video is set:

✅ Video nastaveno  [Zrušit video]

🔄 Data Flow

Loading Club Videos

1. Admin opens event modal
   ↓
2. useEffect triggers on mount
   ↓
3. getCachedYouTube() called
   ↓
4. Fetches from: /youtube/videos
   ↓
5. Fallback: /cache/prefetch/youtube_channel.json
   ↓
6. Videos sorted by date (newest first)
   ↓
7. Limited to 20 videos
   ↓
8. Stored in clubVideos state
   ↓
9. Rendered in scrollable list

Video Selection

User clicks video in list
   ↓
onClick handler:
   - Set youtube_url to video URL
   - Show toast notification
   ↓
UI updates:
   - Red border on selected video
   - "Vybráno" badge appears
   - "Video nastaveno" status shown
   ↓
User saves event
   ↓
youtube_url included in payload
   ↓
Saved to database

Frontend Display

Event detail page loads
   ↓
Checks if youtube_url exists
   ↓
If yes:
   - Parse video ID from URL
   - Generate embed URL
   - Render responsive 16:9 iframe
   ↓
Video appears between map and content

📊 Video Source Comparison

Feature Club Videos Tab Custom URL Tab
Source Club's YouTube channel Any YouTube video
Selection Visual gallery Manual input
Preview Thumbnail + metadata URL only
Videos Auto-loaded (20 recent) User provides
Use Case Club content External/unlisted videos
Ease Click to select Copy/paste URL

💡 Use Cases

Use Case 1: Match Highlights

Event: Vítězství 3:1 vs Sparta
Video: "Match Highlights" from club channel

Admin:
1. Open event
2. Click "Z kanálu klubu"
3. Find "Match Highlights vs Sparta"
4. Click thumbnail
5. Save

Result: Highlights embedded in event page!

Use Case 2: Training Announcement

Event: Trénink mládeže
Video: "Training drill tutorial" from external channel

Admin:
1. Open event
2. Click "Vlastní odkaz"
3. Paste: https://www.youtube.com/watch?v=xyz789
4. Save

Result: Tutorial video embedded!

Use Case 3: Tournament Promo

Event: Annual Tournament 2024
Video: "Tournament Promo 2024" from club channel

Admin:
1. Click "Z kanálu klubu"
2. Scroll to promo video
3. Click to select
4. Save

Result: Promo video on event page!

🎯 Benefits

For Admins

  1. Easier Selection

    • See all videos visually
    • No need to copy URLs
    • One click to select
  2. Better Discovery

    • Browse club videos
    • See thumbnails & titles
    • View publish dates & views
  3. Flexibility

    • Use club videos OR
    • Use any YouTube video
    • Easy switching between options

For Visitors

  1. Consistent Content

    • Videos from official club channel
    • Professional content
    • Trusted source
  2. Rich Experience

    • Watch videos inline
    • No need to leave page
    • Responsive on mobile

🔧 Technical Details

State Management

// YouTube videos from club
const [clubVideos, setClubVideos] = useState<YouTubeVideo[]>([]);

// Active tab
const [youtubeTab, setYoutubeTab] = useState<'club' | 'custom'>('club');

Load Videos

useEffect(() => {
  (async () => {
    const ytData = await getCachedYouTube();
    if (ytData?.videos) {
      setClubVideos(ytData.videos.slice(0, 20));
    }
  })();
}, []);

Video Selection Handler

onClick={() => {
  const videoUrl = `https://www.youtube.com/watch?v=${video.video_id}`;
  setEditing(prev => ({ 
    ...(prev || {}), 
    youtube_url: videoUrl 
  }));
  toast({
    title: 'Video vybráno',
    description: video.title,
    status: 'success',
  });
}}

Data Structure

type YouTubeVideo = {
  video_id: string;           // "abc123"
  title: string;              // "Match Highlights"
  thumbnail_url: string;      // "https://i.ytimg.com/..."
  views_text?: string;        // "1.2K views"
  views?: number;             // 1234
  published_text?: string;    // "3 days ago"
  published_date?: string;    // "2024-03-15"
};

🎨 UI Components

Tab Buttons

<HStack mb={3} spacing={2}>
  <Button
    size="sm"
    leftIcon={<FiYoutube />}
    onClick={() => setYoutubeTab('club')}
    variant={youtubeTab === 'club' ? 'solid' : 'outline'}
    colorScheme={youtubeTab === 'club' ? 'red' : 'gray'}
  >
    Z kanálu klubu ({clubVideos.length})
  </Button>
  <Button
    size="sm"
    leftIcon={<FiLink />}
    onClick={() => setYoutubeTab('custom')}
    variant={youtubeTab === 'custom' ? 'solid' : 'outline'}
    colorScheme={youtubeTab === 'custom' ? 'blue' : 'gray'}
  >
    Vlastní odkaz
  </Button>
</HStack>

Video List Item

<HStack
  p={2}
  borderWidth="1px"
  borderColor={isSelected ? 'red.500' : borderColor}
  bg={isSelected ? 'red.50' : cardBg}
  cursor="pointer"
  _hover={{ borderColor: 'red.300', bg: 'red.50' }}
  onClick={() => selectVideo(video)}
>
  <Image
    src={video.thumbnail_url}
    boxSize="60px"
    objectFit="cover"
    borderRadius="md"
  />
  <VStack align="start" flex={1}>
    <Text fontSize="sm" fontWeight="medium">
      {video.title}
    </Text>
    <HStack fontSize="xs" color="gray.500">
      <Text>{video.published_text}</Text>
      <Text> {video.views_text}</Text>
    </HStack>
  </VStack>
  {isSelected && <Badge colorScheme="red">Vybráno</Badge>}
</HStack>

🆚 Before vs After

Before

YouTube Video (volitelné)
┌──────────────────────────────────┐
│ [URL input field]                │
└──────────────────────────────────┘
Paste URL manually

Limitations:

  • No visual preview
  • Must copy URL from YouTube
  • Can't browse club videos
  • No metadata shown

After

YouTube Video (volitelné)
┌────────────────────────────────────┐
│ [Z kanálu klubu] [Vlastní odkaz]  │ ← Tabs
├────────────────────────────────────┤
│ [Thumb] Match Highlights [Vybráno]│ ← Visual gallery
│ [Thumb] Training Session          │
│ [Thumb] Tournament Promo           │
│         ... (scrollable)           │
└────────────────────────────────────┘

Advantages:

  • Visual gallery
  • One-click selection
  • Browse club videos
  • See metadata (views, date)
  • Still supports custom URLs

📱 Responsive Design

Desktop

Wide scrollable gallery
20 videos visible
Large thumbnails (60x60px)

Mobile

Stacked layout
Scrollable list
Same thumbnail size
Touch-friendly selection

🐛 Edge Cases Handled

No Club Videos

Žádná videa z kanálu klubu. 
Nastavte YouTube kanál v Nastavení.

Shows helpful message if:

  • No YouTube channel configured
  • Channel has no videos
  • Fetch failed

Fallback: Use "Vlastní odkaz" tab

Video Already Selected

[Thumb] Selected Video [Vybráno]
       ═══════════════════════
       Red border + badge

Visual indicator prevents double-selection

Remove Selected Video

✅ Video nastaveno  [Zrušit video]

Click "Zrušit video" to clear selection


🔍 Testing Checklist

  • Tab switching works (club ↔ custom)
  • Club videos load on modal open
  • Videos display with thumbnails
  • Click video selects it
  • Selected video shows red border
  • "Vybráno" badge appears
  • Toast notification shows
  • Status indicator appears
  • Custom URL tab works
  • Can paste any YouTube URL
  • Remove video button works
  • Event saves with youtube_url
  • Frontend displays video correctly
  • No club videos shows message
  • Scrolling works (>20 videos)

Used Services

  • getCachedYouTube() - Fetches club videos
  • YouTubeVideo type - Video data structure

UI Components

  • Tab buttons (club/custom)
  • Video gallery (scrollable)
  • Video list items (clickable)
  • Status indicators

Files Modified

  • AdminActivitiesPage.tsx - Added dual YouTube selector
  • Previous: event.ts, ActivityDetailPage.tsx

💡 Future Enhancements

Potential improvements:

  1. Search/Filter - Search club videos by title
  2. Categories - Filter by playlists
  3. Pagination - Load more than 20 videos
  4. Preview - Show video preview on hover
  5. Timestamps - Start video at specific time
  6. Multiple Videos - Attach multiple videos
  7. Auto-Suggest - Suggest related videos
  8. Analytics - Track which videos most used

🎯 Summary

Your Activity events now have professional YouTube integration:

Visual gallery - Browse club videos
🖼️ Thumbnails - See before selecting
👆 One-click - Easy selection
📊 Metadata - Views, dates shown
🔗 Flexible - Club OR custom videos
📱 Responsive - Works on mobile
User-friendly - Intuitive interface

Perfect for:

  • Match highlights
  • Training videos
  • Tournament promos
  • Club announcements
  • Tutorial videos
  • Promotional content

Implementation Date: 2025-10-10
Status: Production Ready
User Experience: Excellent
Admin Efficiency: Significantly Improved 🚀