4NK_IA_front/src/components/FilePreview.tsx

230 lines
7.1 KiB
TypeScript

import React, { useState, useEffect } from 'react'
import {
Box,
Typography,
Paper,
IconButton,
Button,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
CircularProgress,
Alert,
} from '@mui/material'
import {
PictureAsPdf,
Download,
Close,
ZoomIn,
ZoomOut,
NavigateBefore,
NavigateNext,
} from '@mui/icons-material'
import type { Document } from '../types'
interface FilePreviewProps {
document: Document
onClose: () => void
}
export const FilePreview: React.FC<FilePreviewProps> = ({ document, onClose }) => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [page, setPage] = useState(1)
const [scale, setScale] = useState(1.0)
const [numPages, setNumPages] = useState(0)
useEffect(() => {
setLoading(true)
setError(null)
setPage(1)
setScale(1.0)
// Simuler le chargement du PDF
const timer = setTimeout(() => {
setNumPages(3) // Simuler 3 pages
setLoading(false)
}, 1000)
return () => clearTimeout(timer)
}, [document])
const handleDownload = () => {
if (document.previewUrl) {
const link = window.document.createElement('a')
link.href = document.previewUrl
link.download = document.name
link.click()
}
}
const isPDF = document.type.includes('pdf') || document.name.toLowerCase().endsWith('.pdf')
if (!isPDF) {
return (
<Paper sx={{ p: 3, mt: 2 }}>
<Box display="flex" justifyContent="space-between" alignItems="center" mb={2}>
<Typography variant="h6">{document.name}</Typography>
<IconButton onClick={onClose} title="Fermer">
<Close />
</IconButton>
</Box>
<Alert severity="info">
Aperçu non disponible pour ce type de fichier ({document.type})
</Alert>
</Paper>
)
}
return (
<Dialog open onClose={onClose} maxWidth="lg" fullWidth>
<DialogTitle>
<Box display="flex" justifyContent="space-between" alignItems="center">
<Box display="flex" alignItems="center" gap={1}>
<PictureAsPdf color="error" />
<Typography variant="h6">{document.name}</Typography>
</Box>
<IconButton onClick={onClose} title="Fermer">
<Close />
</IconButton>
</Box>
</DialogTitle>
<DialogContent dividers>
{loading && (
<Box display="flex" justifyContent="center" alignItems="center" minHeight="400px">
<CircularProgress />
<Typography variant="body2" sx={{ ml: 2 }}>
Chargement du PDF...
</Typography>
</Box>
)}
{error && (
<Alert severity="error" sx={{ mb: 2 }}>
{error}
</Alert>
)}
{!loading && !error && (
<Box>
{/* Contrôles de navigation */}
<Box display="flex" justifyContent="space-between" alignItems="center" mb={2}>
<Box display="flex" alignItems="center" gap={1}>
<Button
variant="outlined"
size="small"
startIcon={<NavigateBefore />}
onClick={() => setPage(prev => Math.max(prev - 1, 1))}
disabled={page <= 1}
>
Précédent
</Button>
<Typography variant="body2">
Page {page} sur {numPages}
</Typography>
<Button
variant="outlined"
size="small"
endIcon={<NavigateNext />}
onClick={() => setPage(prev => Math.min(prev + 1, numPages))}
disabled={page >= numPages}
>
Suivant
</Button>
</Box>
<Box display="flex" alignItems="center" gap={1}>
<Button
variant="outlined"
size="small"
startIcon={<ZoomOut />}
onClick={() => setScale(prev => Math.max(prev - 0.2, 0.5))}
>
Zoom -
</Button>
<Typography variant="body2">
{Math.round(scale * 100)}%
</Typography>
<Button
variant="outlined"
size="small"
startIcon={<ZoomIn />}
onClick={() => setScale(prev => Math.min(prev + 0.2, 2.0))}
>
Zoom +
</Button>
</Box>
</Box>
{/* Aperçu PDF avec viewer intégré */}
<Box sx={{
border: '1px solid',
borderColor: 'grey.300',
borderRadius: 1,
overflow: 'hidden',
maxHeight: '70vh',
display: 'flex',
justifyContent: 'center',
backgroundColor: 'grey.50'
}}>
{document.previewUrl ? (
<Box sx={{ width: '100%', height: '600px' }}>
{/* Utiliser un viewer PDF intégré */}
<iframe
src={`${document.previewUrl}#toolbar=1&navpanes=1&scrollbar=1&page=1&view=FitH`}
width="100%"
height="100%"
style={{
border: 'none',
transform: `scale(${scale})`,
transformOrigin: 'top left',
width: `${100 / scale}%`,
height: `${600 / scale}px`
}}
title={`Aperçu de ${document.name}`}
onLoad={() => setLoading(false)}
onError={() => {
setError('Erreur de chargement du PDF')
setLoading(false)
}}
/>
</Box>
) : (
<Box display="flex" justifyContent="center" alignItems="center" minHeight="400px">
<Box textAlign="center">
<PictureAsPdf sx={{ fontSize: 64, color: 'error.main', mb: 2 }} />
<Typography variant="h6" gutterBottom>
Aperçu PDF
</Typography>
<Typography variant="body2" color="text.secondary">
Le fichier PDF "{document.name}" a é uploadé avec succès.
</Typography>
<Typography variant="body2" color="text.secondary">
Taille: {(document.size / 1024 / 1024).toFixed(2)} MB
</Typography>
</Box>
</Box>
)}
</Box>
</Box>
)}
</DialogContent>
<DialogActions>
<Button onClick={onClose}>
Fermer
</Button>
<Button
variant="contained"
startIcon={<Download />}
onClick={handleDownload}
disabled={!document.previewUrl}
>
Télécharger
</Button>
</DialogActions>
</Dialog>
)
}