import React, { useEffect, useState } from 'react'; import { CondoService } from '../services/mockDb'; import { Document, Condo } from '../types'; import { FileText, Download, Eye, Upload, Tag, Search, Trash2, X, Plus, Filter, Image as ImageIcon, File } from 'lucide-react'; export const DocumentsPage: React.FC = () => { const user = CondoService.getCurrentUser(); const isPrivileged = user?.role === 'admin' || user?.role === 'poweruser'; const [documents, setDocuments] = useState([]); const [loading, setLoading] = useState(true); const [activeCondo, setActiveCondo] = useState(undefined); // Filtering const [searchTerm, setSearchTerm] = useState(''); const [selectedTags, setSelectedTags] = useState([]); const [allTags, setAllTags] = useState([]); // Upload Modal const [showUploadModal, setShowUploadModal] = useState(false); const [uploadForm, setUploadForm] = useState<{ title: string; description: string; tags: string[]; currentTagInput: string; file: File | null; }>({ title: '', description: '', tags: [], currentTagInput: '', file: null }); const [isUploading, setIsUploading] = useState(false); // Preview Modal const [previewDoc, setPreviewDoc] = useState<{doc: Document, data: string} | null>(null); useEffect(() => { loadData(); }, []); const loadData = async () => { setLoading(true); try { const condo = await CondoService.getActiveCondo(); setActiveCondo(condo); // Verify method exists before calling to avoid crash if service is outdated if (typeof CondoService.getDocuments === 'function') { const docs = await CondoService.getDocuments(); setDocuments(docs); // Extract unique tags const tags = new Set(); docs.forEach(d => d.tags.forEach(t => tags.add(t))); setAllTags(Array.from(tags).sort()); } else { console.error("CondoService.getDocuments is missing"); } } catch(e) { console.error(e); } finally { setLoading(false); } }; const handleFileUpload = (e: React.ChangeEvent) => { if (e.target.files && e.target.files.length > 0) { setUploadForm({ ...uploadForm, file: e.target.files[0] }); } }; const addTag = () => { if (uploadForm.currentTagInput.trim() && !uploadForm.tags.includes(uploadForm.currentTagInput.trim())) { setUploadForm({ ...uploadForm, tags: [...uploadForm.tags, uploadForm.currentTagInput.trim()], currentTagInput: '' }); } }; const removeTag = (tagToRemove: string) => { setUploadForm({ ...uploadForm, tags: uploadForm.tags.filter(t => t !== tagToRemove) }); }; const handleUploadSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!uploadForm.file) return; setIsUploading(true); try { // Convert FileReader to Promise to handle errors in the main try/catch block const base64 = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(uploadForm.file!); reader.onload = () => resolve(reader.result as string); reader.onerror = error => reject(error); }); if (typeof CondoService.uploadDocument !== 'function') { throw new Error("Il metodo uploadDocument non è disponibile nel servizio."); } await CondoService.uploadDocument({ title: uploadForm.title, description: uploadForm.description, fileName: uploadForm.file.name, fileType: uploadForm.file.type, fileSize: uploadForm.file.size, tags: uploadForm.tags, fileData: base64 }); setIsUploading(false); setShowUploadModal(false); setUploadForm({ title: '', description: '', tags: [], currentTagInput: '', file: null }); loadData(); } catch(e) { console.error("Upload error:", e); alert("Errore durante l'upload. Riprova o contatta l'assistenza."); setIsUploading(false); } }; const handleDelete = async (id: string) => { if (!confirm("Eliminare questo documento?")) return; try { await CondoService.deleteDocument(id); loadData(); } catch(e) { alert("Errore eliminazione"); } }; const handlePreview = async (doc: Document) => { try { const data = await CondoService.getDocumentDownload(doc.id); if (doc.fileType === 'application/pdf' || doc.fileType.startsWith('image/')) { setPreviewDoc({ doc, data: data.data }); } else { // Force download const link = document.createElement("a"); link.href = data.data; link.download = data.fileName; link.click(); } } catch(e) { alert("Errore apertura file"); } }; const filteredDocs = documents.filter(d => { const matchesSearch = d.title.toLowerCase().includes(searchTerm.toLowerCase()) || (d.description && d.description.toLowerCase().includes(searchTerm.toLowerCase())); const matchesTags = selectedTags.length === 0 || selectedTags.every(t => d.tags.includes(t)); return matchesSearch && matchesTags; }); const toggleFilterTag = (tag: string) => { if (selectedTags.includes(tag)) { setSelectedTags(selectedTags.filter(t => t !== tag)); } else { setSelectedTags([...selectedTags, tag]); } }; return (
{/* Sidebar Filters */}

Filtra per Tag

{allTags.length === 0 &&

Nessun tag disponibile.

} {allTags.map(tag => ( ))}
{selectedTags.length > 0 && ( )}
{/* Main Content */}

Documenti

Archivio digitale {activeCondo?.name}

{isPrivileged && ( )}
{/* Search Bar */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-3 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500 shadow-sm" />
{/* Grid */}
{filteredDocs.length === 0 ? (
{loading ? "Caricamento..." : "Nessun documento trovato."}
) : ( filteredDocs.map(doc => (
{doc.fileType === 'application/pdf' ? : doc.fileType.startsWith('image/') ? : }

{doc.title}

{new Date(doc.uploadDate).toLocaleDateString()} • {(doc.fileSize / 1024 / 1024).toFixed(2)} MB

{doc.tags.map(t => ( {t} ))}
{doc.description &&

{doc.description}

}
{isPrivileged && ( )}
)) )}
{/* Upload Modal */} {showUploadModal && (

Carica Documento

setUploadForm({...uploadForm, title: e.target.value})} required />