133 lines
4.9 KiB
JavaScript
133 lines
4.9 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { FileText, Download, Eye, Loader } from 'lucide-react';
|
|
|
|
const MedicalDocuments = ({ demandeId }) => {
|
|
const [documents, setDocuments] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
|
|
useEffect(() => {
|
|
const fetchDocuments = async () => {
|
|
if (!demandeId) {
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
setLoading(true);
|
|
const response = await fetch(`/api/medical-documents/${demandeId}`);
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
setDocuments(data.documents || []);
|
|
} else {
|
|
setError(data.message);
|
|
}
|
|
} catch (err) {
|
|
console.error('Erreur récupération documents:', err);
|
|
setError('Impossible de charger les documents');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchDocuments();
|
|
}, [demandeId]);
|
|
|
|
const formatFileSize = (bytes) => {
|
|
if (bytes === 0) return '0 B';
|
|
const k = 1024;
|
|
const sizes = ['B', 'KB', 'MB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
};
|
|
|
|
const getFileIcon = (type) => {
|
|
if (type === 'application/pdf') {
|
|
return (
|
|
<svg className="w-5 h-5 text-red-600" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fillRule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clipRule="evenodd" />
|
|
</svg>
|
|
);
|
|
}
|
|
return (
|
|
<svg className="w-5 h-5 text-green-600" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fillRule="evenodd" d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z" clipRule="evenodd" />
|
|
</svg>
|
|
);
|
|
};
|
|
|
|
const formatDate = (dateString) => {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleDateString('fr-FR', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
};
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="flex items-center justify-center py-4">
|
|
<Loader className="w-5 h-5 animate-spin text-gray-400" />
|
|
<span className="ml-2 text-sm text-gray-500">Chargement...</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="text-sm text-red-600 py-2">
|
|
Erreur : {error}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (documents.length === 0) {
|
|
return null; // Ne rien afficher s'il n'y a pas de documents
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<p className="text-gray-500 mb-2">
|
|
Justificatifs médicaux ({documents.length})
|
|
</p>
|
|
<div className="space-y-2">
|
|
{documents.map((doc) => (
|
|
<div
|
|
key={doc.id}
|
|
className="flex items-center justify-between p-3 bg-gray-50 rounded-lg border border-gray-200 hover:bg-gray-100 transition-colors"
|
|
>
|
|
<div className="flex items-center gap-3 flex-1 min-w-0">
|
|
<div className="flex-shrink-0">
|
|
{getFileIcon(doc.type)}
|
|
</div>
|
|
<div className="min-w-0 flex-1">
|
|
<p className="text-sm font-medium text-gray-900 truncate">
|
|
{doc.nom}
|
|
</p>
|
|
<div className="flex items-center gap-2 text-xs text-gray-500">
|
|
<span>{formatFileSize(doc.taille)}</span>
|
|
<span>•</span>
|
|
<span>{formatDate(doc.date)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<a
|
|
href={`${doc.downloadUrl}`}
|
|
download
|
|
className="flex-shrink-0 p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
|
|
title="Télécharger"
|
|
>
|
|
<Download className="w-4 h-4" />
|
|
</a>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MedicalDocuments; |