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.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 (
{!playing && (
)}
{mode === 'lowcost' ? 'LOW COST' : 'PREMIUM'}
{video.title || 'Untitled'}
{video.duration?.toFixed(0)}s · ${video.cost_estimate?.total?.toFixed(2) || '?'}
{caption && (
{caption}
)}
);
}