import { useState, useEffect } from 'react'; import { Card, CardMedia, CardActionArea, Box, IconButton, CircularProgress, Typography, Checkbox, } from '@mui/material'; import { PlayCircleOutline as VideoIcon, CheckCircle as CheckedIcon, } from '@mui/icons-material'; import type { Asset } from '../types'; import api from '../services/api'; interface MediaCardProps { asset: Asset; selected?: boolean; onSelect?: (assetId: string, selected: boolean) => void; onClick?: () => void; } export default function MediaCard({ asset, selected, onSelect, onClick }: MediaCardProps) { const [thumbnailUrl, setThumbnailUrl] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); useEffect(() => { loadThumbnail(); }, [asset.id]); const loadThumbnail = async () => { try { setLoading(true); setError(false); // Try to get thumbnail first, fallback to original for photos const url = asset.storage_key_thumb ? await api.getDownloadUrl(asset.id, 'thumb') : asset.type === 'photo' ? await api.getDownloadUrl(asset.id, 'original') : ''; setThumbnailUrl(url); } catch (err) { console.error('Failed to load thumbnail:', err); setError(true); } finally { setLoading(false); } }; const formatFileSize = (bytes: number): string => { if (bytes < 1024) return bytes + ' B'; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; return (bytes / (1024 * 1024 * 1024)).toFixed(1) + ' GB'; }; const formatDate = (dateString: string): string => { const date = new Date(dateString); return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short', year: 'numeric', }); }; const handleSelect = (e: React.MouseEvent) => { e.stopPropagation(); if (onSelect) { onSelect(asset.id, !selected); } }; return ( {loading && ( )} {error && ( Ошибка загрузки )} {!loading && !error && thumbnailUrl && ( )} {asset.type === 'video' && ( )} {asset.original_filename} {formatFileSize(asset.size_bytes)} • {formatDate(asset.created_at)} {onSelect && ( } checkedIcon={} sx={{ position: 'absolute', top: 8, left: 8, }} /> )} ); }