import React, { useState, useEffect, useRef } from 'react'; import { Film, Download, Copy, Check, ExternalLink, Loader2, Play, User } from 'lucide-react'; import { getApiUrl } from '../config'; export default function UGCGallery() { const [tab, setTab] = useState('videos'); const [videos, setVideos] = useState([]); const [avatars, setAvatars] = useState([]); const [loading, setLoading] = useState(true); const [copied, setCopied] = useState(''); useEffect(() => { setLoading(true); Promise.all([ fetch(getApiUrl('/api/saasshorts/gallery?limit=100')).then(r => r.ok ? r.json() : { videos: [] }), fetch(getApiUrl('/api/saasshorts/actor-gallery')).then(r => r.ok ? r.json() : { images: [] }), ]) .then(([vData, aData]) => { setVideos(vData.videos || []); setAvatars(aData.images || []); }) .catch(() => {}) .finally(() => setLoading(false)); }, []); const handleCopy = (text, id) => { navigator.clipboard.writeText(text); setCopied(id); setTimeout(() => setCopied(''), 2000); }; if (loading) { return (
Loading gallery...
); } return (
{/* Header */}

UGC Gallery

{videos.length} videos · {avatars.length} avatars

Public Gallery
{/* Tabs */}
{/* Videos Tab */} {tab === 'videos' && ( videos.length === 0 ? (

No videos yet. Generate one from AI Shorts.

) : (
{videos.map((video) => ( ))}
) )} {/* Avatars Tab */} {tab === 'avatars' && ( avatars.length === 0 ? (

No avatars yet. Generate actors from AI Shorts.

) : (
{avatars.map((avatar, i) => ( ))}
) )}
); } function AvatarCard({ avatar, copied, onCopy }) { return (
Avatar
{avatar.description ? (

{avatar.description}

) : (

No description

)} Download
); } function VideoCard({ video, copied, onCopy }) { const videoRef = useRef(null); const [playing, setPlaying] = useState(false); const handleMouseEnter = () => { if (videoRef.current) { videoRef.current.play().catch(() => {}); setPlaying(true); } }; const handleMouseLeave = () => { if (videoRef.current) { videoRef.current.pause(); videoRef.current.currentTime = 0; setPlaying(false); } }; const mode = video.video_mode; const caption = video.caption || ''; const hashtags = (video.hashtags || []).join(' '); return (

{video.title || 'Untitled'}

{video.duration?.toFixed(0)}s · ${video.cost_estimate?.total?.toFixed(2) || '?'}

{caption && (

{caption}

)}
Download View
); }