'use client'; import { useState, useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { assetsApi } from '@/lib/api'; import { Clock, FileImage, FileVideo, FileAudio, FileText, ChevronRight, GripVertical, ChevronLeft, ChevronLast, ChevronFirst } from 'lucide-react'; import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'; const RECENT_LIMIT = 10; export default function RecentAssets() { const router = useRouter(); const [assets, setAssets] = useState([]); const [loading, setLoading] = useState(true); const [isCollapsed, setIsCollapsed] = useState(false); const [selectedAssetId, setSelectedAssetId] = useState(null); const fetchRecentAssets = async () => { try { const response = await assetsApi.list({ limit: RECENT_LIMIT, sort: 'created_at', order: 'desc' }); setAssets(response.data); } catch (err) { console.error("Failed to fetch recent assets", err); } finally { setLoading(false); } }; useEffect(() => { fetchRecentAssets(); const interval = setInterval(fetchRecentAssets, 30000); return () => clearInterval(interval); }, []); const renderPreview = (asset: any) => { if (asset.mime_type.startsWith('image/')) { return (
preview
); } if (asset.mime_type.startsWith('video/')) { return (
); } if (asset.mime_type.startsWith('audio/')) { return
; } return
; }; const handleClick = (asset: any) => { if (asset.mime_type.startsWith('image/')) { router.push(`/image/upscale?assetId=${asset.id}`); } else if (asset.mime_type.startsWith('video/')) { router.push(`/video/upscale?assetId=${asset.id}`); } else if (asset.mime_type.startsWith('audio/')) { router.push(`/audio/voice-to-text?assetId=${asset.id}`); } else { router.push(`/files?assetId=${asset.id}`); } }; const handleAction = (e: React.MouseEvent, asset: any, action: string) => { e.stopPropagation(); setSelectedAssetId(null); switch (action) { case 'upscale_image': router.push(`/image/upscale?assetId=${asset.id}`); break; case 'img_to_video': router.push(`/video/generate?assetId=${asset.id}`); break; case 'remove_bg': router.push(`/image/remove-bg?assetId=${asset.id}`); break; case 'upscale_video': router.push(`/video/upscale?assetId=${asset.id}`); break; case 'subtitles': router.push(`/video/subtitles?assetId=${asset.id}`); break; case 'transcribe': router.push(`/audio/voice-to-text?assetId=${asset.id}`); break; case 'alt_text': router.push(`/text/alt-text?assetId=${asset.id}`); break; default: router.push(`/files?assetId=${asset.id}`); } }; const toggleMenu = (e: React.MouseEvent, assetId: string) => { e.stopPropagation(); if (selectedAssetId === assetId) { setSelectedAssetId(null); } else { setSelectedAssetId(assetId); } }; const handleDragEnd = (result: any) => { if (!result.destination) return; const items = Array.from(assets); const [reorderedItem] = items.splice(result.source.index, 1); items.splice(result.destination.index, 0, reorderedItem); setAssets(items); }; if (loading && assets.length === 0) { return (
); } return (
{!isCollapsed && (

Recent

)}
{!isCollapsed && (
{(provided: any) => (
{assets.map((asset, index) => ( {(provided: any, snapshot: any) => (
{ // Standard HTML5 drag start // We pass a JSON string with asset details const dragData = JSON.stringify({ id: asset.id, url: `/api/v1/assets/${asset.id}/download`, filename: asset.original_filename, mime_type: asset.mime_type, type: 'forge-asset' }); e.dataTransfer.setData('application/json', dragData); e.dataTransfer.setData('text/plain', dragData); // Fallback // If dragging an image, try to set the drag image if (asset.mime_type.startsWith('image/')) { // Optional: Set custom drag image if needed, but browser default is usually okay for img tags // But here we are dragging a div. // e.dataTransfer.setDragImage(e.currentTarget.querySelector('img'), 0, 0); } }} className={`group relative bg-forge-gray/30 hover:bg-forge-gray rounded-xl p-3 border border-transparent hover:border-gray-700 transition-all cursor-pointer ${snapshot.isDragging ? 'shadow-xl ring-2 ring-forge-yellow border-forge-yellow z-50' : '' }`} >
{renderPreview(asset)}

{asset.original_filename}

{(asset.file_size_bytes / 1024).toFixed(1)} KB

{/* Context Menu */} {selectedAssetId === asset.id && (
{asset.mime_type.startsWith('image/') && ( <> )} {asset.mime_type.startsWith('video/') && ( <> )} {asset.mime_type.startsWith('audio/') && ( )}
)}
)}
))} {provided.placeholder} {assets.length === 0 && (

No recent activity

)}
)}
)} {isCollapsed && (
{assets.slice(0, 5).map(asset => (
setIsCollapsed(false)}> {asset.mime_type.startsWith('image/') ? ( ) : (
)}
))}
)}
); }