import { useState, useEffect } from 'react'; import { Box, Grid, Fab, Typography, CircularProgress, Button, Select, MenuItem, FormControl, InputLabel, Dialog, DialogTitle, DialogContent, DialogActions, TextField, Alert, Snackbar, } from '@mui/material'; import { Add as AddIcon, FilterList as FilterIcon } from '@mui/icons-material'; import Layout from '../components/Layout'; import MediaCard from '../components/MediaCard'; import UploadDialog from '../components/UploadDialog'; import ViewerModal from '../components/ViewerModal'; import type { Asset, AssetType } from '../types'; import api from '../services/api'; export default function LibraryPage() { const [assets, setAssets] = useState([]); const [loading, setLoading] = useState(true); const [hasMore, setHasMore] = useState(false); const [cursor, setCursor] = useState(); const [filter, setFilter] = useState('all'); const [uploadOpen, setUploadOpen] = useState(false); const [viewerAsset, setViewerAsset] = useState(null); const [shareDialogOpen, setShareDialogOpen] = useState(false); const [shareAssetId, setShareAssetId] = useState(''); const [shareLink, setShareLink] = useState(''); const [snackbarOpen, setSnackbarOpen] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); useEffect(() => { loadAssets(true); }, [filter]); const loadAssets = async (reset: boolean = false) => { try { setLoading(true); const response = await api.listAssets({ cursor: reset ? undefined : cursor, limit: 50, type: filter === 'all' ? undefined : filter, }); setAssets(reset ? response.items : [...assets, ...response.items]); setHasMore(response.has_more); setCursor(response.next_cursor); } catch (error) { console.error('Failed to load assets:', error); } finally { setLoading(false); } }; const handleUploadComplete = () => { setUploadOpen(false); loadAssets(true); showSnackbar('Файлы успешно загружены'); }; const handleDelete = async (assetId: string) => { try { await api.deleteAsset(assetId); setAssets(assets.filter((a) => a.id !== assetId)); showSnackbar('Файл перемещен в корзину'); } catch (error) { console.error('Failed to delete asset:', error); showSnackbar('Ошибка при удалении файла'); } }; const handleShare = (assetId: string) => { setShareAssetId(assetId); setShareDialogOpen(true); }; const handleCreateShare = async () => { try { const share = await api.createShare({ asset_id: shareAssetId, expires_in_seconds: 86400 * 7, // 7 days }); const link = `${window.location.origin}/share/${share.token}`; setShareLink(link); showSnackbar('Ссылка создана'); } catch (error) { console.error('Failed to create share:', error); showSnackbar('Ошибка создания ссылки'); } }; const handleCopyShareLink = () => { // Fallback for HTTP (clipboard API requires HTTPS) if (navigator.clipboard && window.isSecureContext) { navigator.clipboard.writeText(shareLink); } else { // Fallback method for HTTP const textArea = document.createElement('textarea'); textArea.value = shareLink; textArea.style.position = 'fixed'; textArea.style.left = '-999999px'; document.body.appendChild(textArea); textArea.focus(); textArea.select(); try { document.execCommand('copy'); } catch (err) { console.error('Failed to copy:', err); } document.body.removeChild(textArea); } showSnackbar('Ссылка скопирована'); setShareDialogOpen(false); setShareLink(''); }; const showSnackbar = (message: string) => { setSnackbarMessage(message); setSnackbarOpen(true); }; return ( {/* Filters */} Тип файлов {/* Content */} {loading && assets.length === 0 && ( )} {!loading && assets.length === 0 && ( Нет файлов Нажмите кнопку + чтобы загрузить файлы )} {assets.length > 0 && ( <> {assets.map((asset) => ( setViewerAsset(asset)} /> ))} {hasMore && ( )} )} {/* FAB */} setUploadOpen(true)} > {/* Upload Dialog */} setUploadOpen(false)} onComplete={handleUploadComplete} /> {/* Viewer Modal */} setViewerAsset(null)} onDelete={handleDelete} onShare={handleShare} /> {/* Share Dialog */} setShareDialogOpen(false)}> Поделиться файлом {!shareLink ? ( Создать публичную ссылку на файл? Ссылка будет действительна 7 дней. ) : ( )} {!shareLink ? ( ) : ( )} {/* Snackbar */} setSnackbarOpen(false)} message={snackbarMessage} /> ); }