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); // Load media through backend proxy with auth const kind = asset.storage_key_thumb ? 'thumb' : 'original'; if (asset.type === 'photo' || asset.storage_key_thumb) { const blob = await api.getMediaBlob(asset.id, kind); const url = URL.createObjectURL(blob); 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, }} /> )} ); }