154 lines
5.4 KiB
TypeScript
154 lines
5.4 KiB
TypeScript
|
|
import React, { useRef, useState } from 'react'
|
|||
|
|
import { FaTimes, FaFile, FaEye, FaDownload, FaTrash } from 'react-icons/fa'
|
|||
|
|
import { ClassDocumentDto } from '@/proxy/classroom/models'
|
|||
|
|
|
|||
|
|
interface DocumentsPanelProps {
|
|||
|
|
user: { role: string; name: string }
|
|||
|
|
documents: ClassDocumentDto[]
|
|||
|
|
onUpload: (file: File) => void
|
|||
|
|
onDelete: (id: string) => void
|
|||
|
|
onView: (doc: ClassDocumentDto) => void
|
|||
|
|
onClose: () => void
|
|||
|
|
formatFileSize: (bytes: number) => string
|
|||
|
|
getFileIcon: (type: string) => JSX.Element
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const DocumentsPanel: React.FC<DocumentsPanelProps> = ({
|
|||
|
|
user,
|
|||
|
|
documents,
|
|||
|
|
onUpload,
|
|||
|
|
onDelete,
|
|||
|
|
onView,
|
|||
|
|
onClose,
|
|||
|
|
formatFileSize,
|
|||
|
|
getFileIcon,
|
|||
|
|
}) => {
|
|||
|
|
const fileInputRef = useRef<HTMLInputElement>(null)
|
|||
|
|
const [dragOver, setDragOver] = useState(false)
|
|||
|
|
|
|||
|
|
const handleDrop = (e: React.DragEvent) => {
|
|||
|
|
e.preventDefault()
|
|||
|
|
setDragOver(false)
|
|||
|
|
if (user.role !== 'teacher') return
|
|||
|
|
const files = Array.from(e.dataTransfer.files)
|
|||
|
|
files.forEach((file) => onUpload(file))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|||
|
|
if (user.role !== 'teacher') return
|
|||
|
|
const files = Array.from(e.target.files || [])
|
|||
|
|
files.forEach((file) => onUpload(file))
|
|||
|
|
if (fileInputRef.current) fileInputRef.current.value = ''
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="h-full bg-white flex flex-col text-gray-900">
|
|||
|
|
{/* Header */}
|
|||
|
|
<div className="p-4 border-b border-gray-200">
|
|||
|
|
<div className="flex items-center justify-between">
|
|||
|
|
<h3 className="text-lg font-semibold text-gray-900">Sınıf Dokümanları</h3>
|
|||
|
|
<button onClick={onClose}>
|
|||
|
|
<FaTimes className="text-gray-500" />
|
|||
|
|
</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* Content */}
|
|||
|
|
<div className="flex-1 overflow-y-auto p-4">
|
|||
|
|
{/* Upload Area (Teacher Only) */}
|
|||
|
|
{user.role === 'teacher' && (
|
|||
|
|
<div
|
|||
|
|
className={`border-2 border-dashed rounded-lg p-6 mb-4 text-center transition-colors ${
|
|||
|
|
dragOver ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-gray-400'
|
|||
|
|
}`}
|
|||
|
|
onDrop={handleDrop}
|
|||
|
|
onDragOver={(e) => {
|
|||
|
|
e.preventDefault()
|
|||
|
|
setDragOver(true)
|
|||
|
|
}}
|
|||
|
|
onDragLeave={() => setDragOver(false)}
|
|||
|
|
>
|
|||
|
|
<FaFile size={32} className="mx-auto text-gray-400 mb-2" />
|
|||
|
|
<p className="text-sm font-medium text-gray-700 mb-2">Doküman Yükle</p>
|
|||
|
|
<p className="text-xs text-gray-500 mb-3">Dosyaları buraya sürükleyin veya seçin</p>
|
|||
|
|
<button
|
|||
|
|
onClick={() => fileInputRef.current?.click()}
|
|||
|
|
className="px-3 py-1 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 transition-colors"
|
|||
|
|
>
|
|||
|
|
Dosya Seç
|
|||
|
|
</button>
|
|||
|
|
<input
|
|||
|
|
ref={fileInputRef}
|
|||
|
|
type="file"
|
|||
|
|
multiple
|
|||
|
|
onChange={handleFileSelect}
|
|||
|
|
className="hidden"
|
|||
|
|
accept=".pdf,.doc,.docx,.ppt,.pptx,.jpg,.jpeg,.png,.gif,.odp"
|
|||
|
|
/>
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
|
|||
|
|
{/* Documents List */}
|
|||
|
|
{documents.length === 0 ? (
|
|||
|
|
<div className="text-center py-8 text-gray-500">
|
|||
|
|
<FaFile size={32} className="mx-auto mb-4 text-gray-300" />
|
|||
|
|
<p className="text-sm">Henüz doküman yüklenmemiş.</p>
|
|||
|
|
</div>
|
|||
|
|
) : (
|
|||
|
|
<div className="space-y-3">
|
|||
|
|
{documents.map((doc) => (
|
|||
|
|
<div
|
|||
|
|
key={doc.id}
|
|||
|
|
className="flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:shadow-sm transition-shadow"
|
|||
|
|
>
|
|||
|
|
<div className="flex items-center space-x-3 min-w-0 flex-1">
|
|||
|
|
<div className="text-lg flex-shrink-0">{getFileIcon(doc.type)}</div>
|
|||
|
|
<div className="min-w-0 flex-1">
|
|||
|
|
<h4 className="font-medium text-gray-800 text-sm truncate">{doc.name}</h4>
|
|||
|
|
<p className="text-xs text-gray-600">
|
|||
|
|
{formatFileSize(doc.size)} •{' '}
|
|||
|
|
{new Date(doc.uploadedAt).toLocaleDateString('tr-TR')}
|
|||
|
|
</p>
|
|||
|
|
<p className="text-xs text-gray-500">{doc.uploadedBy}</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div className="flex items-center space-x-1 flex-shrink-0">
|
|||
|
|
<button
|
|||
|
|
onClick={() => onView(doc)}
|
|||
|
|
className="p-1 text-blue-600 hover:bg-blue-50 rounded transition-colors"
|
|||
|
|
title="Görüntüle"
|
|||
|
|
>
|
|||
|
|
<FaEye size={12} />
|
|||
|
|
</button>
|
|||
|
|
|
|||
|
|
<a
|
|||
|
|
href={doc.url}
|
|||
|
|
download={doc.name}
|
|||
|
|
className="p-1 text-green-600 hover:bg-green-50 rounded transition-colors"
|
|||
|
|
title="İndir"
|
|||
|
|
>
|
|||
|
|
<FaDownload size={12} />
|
|||
|
|
</a>
|
|||
|
|
|
|||
|
|
{user.role === 'teacher' && (
|
|||
|
|
<button
|
|||
|
|
onClick={() => onDelete(doc.id)}
|
|||
|
|
className="p-1 text-red-600 hover:bg-red-50 rounded transition-colors"
|
|||
|
|
title="Sil"
|
|||
|
|
>
|
|||
|
|
<FaTrash size={12} />
|
|||
|
|
</button>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
))}
|
|||
|
|
</div>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default DocumentsPanel
|