// src/pages/music/components/VideoProjectsTab.jsx import { useState, useEffect, useRef } from 'react'; import { createVideoProject, getVideoProjects, renderVideoProject, exportVideoProject, deleteVideoProject, } from '../../../api'; const COUNTRY_OPTIONS = ['BR', 'US', 'ID', 'MX', 'KR']; const COUNTRY_FLAGS = { BR: '๐Ÿ‡ง๐Ÿ‡ท', US: '๐Ÿ‡บ๐Ÿ‡ธ', ID: '๐Ÿ‡ฎ๐Ÿ‡ฉ', MX: '๐Ÿ‡ฒ๐Ÿ‡ฝ', KR: '๐Ÿ‡ฐ๐Ÿ‡ท' }; export default function VideoProjectsTab({ library, initialTrackId, onClearInitialTrack }) { const [projects, setProjects] = useState([]); const [selectedTrackId, setSelectedTrackId] = useState(initialTrackId ?? ''); const [format, setFormat] = useState('visualizer'); const [countries, setCountries] = useState(['BR']); const [creating, setCreating] = useState(false); const [exportData, setExportData] = useState(null); const [exportingId, setExportingId] = useState(null); const pollRef = useRef(null); // initialTrackId prop ๋ฐ˜์˜ useEffect(() => { if (initialTrackId) { setSelectedTrackId(String(initialTrackId)); onClearInitialTrack?.(); } }, [initialTrackId]); const loadProjects = async () => { try { const data = await getVideoProjects(); setProjects(Array.isArray(data) ? data : data.projects ?? []); } catch (e) { console.error('getVideoProjects:', e); } }; useEffect(() => { loadProjects(); }, []); // ๋ Œ๋”๋ง ์ค‘์ธ ํ”„๋กœ์ ํŠธ๊ฐ€ ์žˆ์œผ๋ฉด 5์ดˆ๋งˆ๋‹ค ํด๋ง useEffect(() => { const hasRendering = projects.some(p => p.status === 'rendering'); if (hasRendering && !pollRef.current) { pollRef.current = setInterval(loadProjects, 5000); } else if (!hasRendering && pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; } return () => { if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; } }; }, [projects]); const toggleCountry = (c) => { setCountries(prev => prev.includes(c) ? prev.filter(x => x !== c) : [...prev, c] ); }; const handleCreate = async () => { if (!selectedTrackId || countries.length === 0) return; setCreating(true); try { await createVideoProject({ track_id: Number(selectedTrackId), format, target_countries: countries, }); await loadProjects(); } catch (e) { console.error('createVideoProject:', e); } finally { setCreating(false); } }; const handleRender = async (id) => { try { await renderVideoProject(id); await loadProjects(); } catch (e) { console.error('renderVideoProject:', e); } }; const handleExport = async (id) => { setExportingId(id); try { const data = await exportVideoProject(id); setExportData({ id, ...data }); } catch (e) { console.error('exportVideoProject:', e); } finally { setExportingId(null); } }; const handleDelete = async (id) => { if (!window.confirm('์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ญ์ œํ• ๊นŒ์š”?')) return; try { await deleteVideoProject(id); setProjects(prev => prev.filter(p => p.id !== id)); if (exportData?.id === id) setExportData(null); } catch (e) { console.error('deleteVideoProject:', e); } }; return (
{/* โ‘  ์ƒˆ ์˜์ƒ ๋งŒ๋“ค๊ธฐ */}

โ‘  ์ƒˆ ์˜์ƒ ๋งŒ๋“ค๊ธฐ

{['visualizer', 'slideshow'].map(f => ( ))}
ํƒ€๊ฒŸ ๊ตญ๊ฐ€ (๋ณต์ˆ˜ ์„ ํƒ)
{COUNTRY_OPTIONS.map(c => ( ))}
{/* โ‘ก ํ”„๋กœ์ ํŠธ ๋ชฉ๋ก */}

โ‘ก ์˜์ƒ ํ”„๋กœ์ ํŠธ

{projects.length === 0 ? (

ํŠธ๋ž™์„ ์„ ํƒํ•ด ์˜์ƒ์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”

) : (
{projects.map(p => ( ))}
)}
{/* โ‘ข ๋‚ด๋ณด๋‚ด๊ธฐ ํŒจํ‚ค์ง€ */} {exportData && (

โ‘ข ๋‚ด๋ณด๋‚ด๊ธฐ ํŒจํ‚ค์ง€

{exportData.mp4_url && ( ๐Ÿ“น output.mp4 ๋‹ค์šด๋กœ๋“œ )} {exportData.thumbnail_url && ( ๐Ÿ–ผ๏ธ thumbnail.jpg )}
{exportData.metadata && (
metadata.json ๋ฏธ๋ฆฌ๋ณด๊ธฐ
                                {JSON.stringify(exportData.metadata, null, 2)}
                            
)}
)}
); } function ProjectCard({ project, onRender, onExport, onDelete, isExporting }) { const STATUS_MAP = { pending: { text: '๋Œ€๊ธฐ', cls: 'yt-status--pending' }, rendering: { text: 'โš™ ์ฒ˜๋ฆฌ์ค‘', cls: 'yt-status--rendering' }, done: { text: 'โœ“ ์™„๋ฃŒ', cls: 'yt-status--done' }, failed: { text: '์‹คํŒจ', cls: 'yt-status--failed' }, }; const s = STATUS_MAP[project.status] ?? { text: project.status, cls: '' }; return (
{project.status === 'rendering' ? 'โš™๏ธ' : project.status === 'done' ? '๐ŸŽฌ' : '๐ŸŽต'}
{project.title ?? `ํ”„๋กœ์ ํŠธ #${project.id}`}
{project.format} ยท {(project.target_countries ?? []).join(' ')}
{project.status === 'rendering' && (
)}
{s.text} {project.status === 'pending' && ( )} {project.status === 'done' && ( )}
); }