import React, { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { getVideosList, deleteVideo } from '../../utils/api'; import { VideoListItem } from '../../types/api'; import SocialPostingModal from '../../components/SocialPostingModal'; interface ADO2ContentsPageProps { onBack: () => void; } const ADO2ContentsPage: React.FC = ({ onBack }) => { const { t } = useTranslation(); const [videos, setVideos] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [page, setPage] = useState(1); const [hasNext, setHasNext] = useState(false); const [hasPrev, setHasPrev] = useState(false); const [totalPages, setTotalPages] = useState(1); const [deleteModalOpen, setDeleteModalOpen] = useState(false); const [deleteTargetId, setDeleteTargetId] = useState(null); const [isDeleting, setIsDeleting] = useState(false); const [uploadModalOpen, setUploadModalOpen] = useState(false); const [uploadTargetVideo, setUploadTargetVideo] = useState(null); const pageSize = 12; useEffect(() => { fetchVideos(); }, [page]); const fetchVideos = async () => { setLoading(true); setError(null); try { const response = await getVideosList(page, pageSize); console.log('[ADO2] API response:', response); console.log('[ADO2] First video item:', response.items[0]); // result_movie_url이 있는 비디오만 필터링 (빈/더미 데이터 제외) const validVideos = response.items.filter(video => video.result_movie_url && video.result_movie_url.trim() !== ''); setVideos(validVideos); setTotal(response.total); setTotalPages(response.total_pages); setHasNext(response.has_next); setHasPrev(response.has_prev); } catch (err) { console.error('Failed to fetch videos:', err); setError(t('ado2Contents.loadFailed')); } finally { setLoading(false); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); return `${year}.${month}.${day}・${hours}:${minutes}`; }; const formatTitle = (storeName: string, dateString: string) => { const date = new Date(dateString); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); return `${storeName} ${month}/${day} ${hours}:${minutes}`; }; const handleDownload = async (videoUrl: string, storeName: string) => { try { const response = await fetch(videoUrl); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${storeName}.mp4`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); } catch (err) { console.error('Download failed:', err); alert(t('ado2Contents.downloadFailed')); } }; const handleDeleteClick = (videoId: number) => { setDeleteTargetId(videoId); setDeleteModalOpen(true); }; const handleUploadClick = (video: VideoListItem) => { console.log('[ADO2] Upload clicked - video object:', video); console.log('[ADO2] video.video_id:', video.video_id); setUploadTargetVideo(video); setUploadModalOpen(true); }; const handleUploadModalClose = () => { setUploadModalOpen(false); setUploadTargetVideo(null); }; const handleDeleteCancel = () => { setDeleteModalOpen(false); setDeleteTargetId(null); }; const handleDeleteConfirm = async () => { if (!deleteTargetId) return; setIsDeleting(true); try { await deleteVideo(deleteTargetId); // 삭제 성공 시 로컬 상태에서 즉시 제거 (UI 즉시 반영) // fetchVideos()를 호출하지 않음 - 서버 캐시 또는 동기화 지연으로 인해 // 삭제된 항목이 다시 나타날 수 있기 때문 setVideos(prev => prev.filter(video => video.video_id !== deleteTargetId)); setTotal(prev => Math.max(0, prev - 1)); setDeleteModalOpen(false); setDeleteTargetId(null); } catch (err) { console.error('Delete failed:', err); alert(t('ado2Contents.deleteFailed')); } finally { setIsDeleting(false); } }; return (
{/* Header */}

{t('ado2Contents.title')}

{t('ado2Contents.totalCount', { count: total })}
{/* Content Grid */} {loading ? (

{t('ado2Contents.loading')}

) : error ? (

{error}

) : videos.length === 0 ? (

{t('ado2Contents.noContent')}

) : ( <>
{videos.map((video) => (
{/* Video Thumbnail */}
{video.result_movie_url ? (
{/* Card Info */}

{formatTitle(video.store_name, video.created_at)}

{formatDate(video.created_at)}

{/* Action Buttons */}
))}
{/* Pagination - 항상 표시 */}
{page} / {totalPages}
)} {/* 삭제 확인 모달 */} {deleteModalOpen && (
e.stopPropagation()}>

{t('ado2Contents.deleteConfirmTitle')}

{t('ado2Contents.deleteConfirmDesc')}

)} {/* 소셜 미디어 업로드 모달 */}
); }; export default ADO2ContentsPage;