diff --git a/frontend/src/tools/dateien.jsx b/frontend/src/tools/dateien.jsx index 961ed35..db5d8b5 100644 --- a/frontend/src/tools/dateien.jsx +++ b/frontend/src/tools/dateien.jsx @@ -1,289 +1,370 @@ -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect, useRef, useCallback } from 'react'; import { api, S } from '../lib.js'; import { useConfirm } from '../confirm.jsx'; -import { UploadIcon, DownloadIcon, TrashIcon, SearchIcon, XIcon, PlusIcon } from '../icons.jsx'; - -function fmtSize(bytes) { - if (bytes < 1024) return `${bytes} B`; - if (bytes < 1024*1024) return `${(bytes/1024).toFixed(1)} KB`; - return `${(bytes/(1024*1024)).toFixed(1)} MB`; -} - -function fmtDate(s) { - return new Date(s).toLocaleDateString('de-DE', { day:'2-digit', month:'2-digit', year:'numeric' }); -} +import { UploadIcon, DownloadIcon, TrashIcon, SearchIcon, PlusIcon, ChevronIcon, DatabaseIcon } from '../icons.jsx'; +const fmtSize = b => b<1024?`${b} B`:b<1024*1024?`${(b/1024).toFixed(1)} KB`:`${(b/(1024*1024)).toFixed(1)} MB`; +const fmtDate = s => new Date(s).toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'numeric'}); const extIcon = name => { - const ext = name.split('.').pop().toLowerCase(); - if (['jpg','jpeg','png','gif','webp'].includes(ext)) return 'πΌ'; - if (['pdf'].includes(ext)) return 'π'; - if (['zip','rar','7z'].includes(ext)) return 'π¦'; - if (['mp4','mov','avi'].includes(ext)) return 'π¬'; - if (['mp3','wav'].includes(ext)) return 'π΅'; - if (['stl','3mf'].includes(ext)) return 'π¨'; - if (['txt','md'].includes(ext)) return 'π'; - if (['xlsx','csv'].includes(ext)) return 'π'; - if (['docx','doc'].includes(ext)) return 'π'; + const e = name.split('.').pop().toLowerCase(); + if (['jpg','jpeg','png','gif','webp'].includes(e)) return 'πΌ'; + if (e==='pdf') return 'π'; if (['zip','rar','7z'].includes(e)) return 'π¦'; + if (['mp4','mov','avi'].includes(e)) return 'π¬'; if (['mp3','wav'].includes(e)) return 'π΅'; + if (['stl','3mf'].includes(e)) return 'π¨'; if (['txt','md'].includes(e)) return 'π'; + if (['xlsx','csv'].includes(e)) return 'π'; if (['docx','doc'].includes(e)) return 'π'; return 'π'; }; -function ShareModal({ file, onClose, toast }) { +// ββ Share Modal βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +function ShareModal({ item, type, onClose, toast }) { const [username, setUsername] = useState(''); const [shares, setShares] = useState([]); - const [busy, setBusy] = useState(false); - - useEffect(() => { - api('/tools/dateien').then(d => { - // find current shares for this file - const allShares = d.own.find(f => f.id === file.id); - // get shares via separate query approach - just reload full list - }).catch(() => {}); - // Load shares from API - api(`/tools/dateien/${file.id}/shares`).then(setShares).catch(() => {}); - }, [file.id]); - + const base = type==='folder' ? `/tools/dateien/folders/${item.id}` : `/tools/dateien/${item.id}`; + useEffect(() => { api(`${base}/shares`).then(setShares).catch(()=>{}); }, [base]); const share = async () => { if (!username.trim()) return; - setBusy(true); - try { - await api(`/tools/dateien/${file.id}/share`, { body: { username: username.trim() } }); - toast(`Mit ${username} geteilt β`); - setUsername(''); - api(`/tools/dateien/${file.id}/shares`).then(setShares).catch(() => {}); - } catch(e) { toast(e.message, 'error'); } finally { setBusy(false); } + try { await api(`${base}/share`,{body:{username:username.trim()}}); toast(`Geteilt β`); setUsername(''); api(`${base}/shares`).then(setShares); } + catch(e) { toast(e.message,'error'); } }; - - const unshare = async userId => { - try { - await api(`/tools/dateien/${file.id}/share/${userId}`, { method: 'DELETE' }); - setShares(p => p.filter(s => s.id !== userId)); - toast('Freigabe entfernt'); - } catch(e) { toast(e.message, 'error'); } + const unshare = async uid => { + try { await api(`${base}/share/${uid}`,{method:'DELETE'}); setShares(p=>p.filter(s=>s.id!==uid)); toast('Freigabe entfernt'); } + catch(e) { toast(e.message,'error'); } }; - - const isMobile = window.innerWidth < 768; + const isMobile = window.innerWidth<768; return ( -