diff --git a/backend/src/tools/dateien/routes.js b/backend/src/tools/dateien/routes.js index c1b6205..e965d06 100644 --- a/backend/src/tools/dateien/routes.js +++ b/backend/src/tools/dateien/routes.js @@ -183,9 +183,11 @@ router.get('/', authenticate, (req, res) => { router.post('/', authenticate, (req, res) => { const uid = req.user.id; - const maxCount = parseInt(getSetting('file_max_count') || '20'); - const count = db.prepare('SELECT COUNT(*) c FROM files WHERE user_id=?').get(uid).c; - if (count >= maxCount) return res.status(400).json({ error: `Maximum ${maxCount} Dateien erlaubt` }); + const maxSizeMb = parseInt(getSetting('file_max_size_mb') || '50'); + const totalLimitMb= parseInt(getSetting('file_total_size_mb') || '500'); + const usedBytes = db.prepare('SELECT COALESCE(SUM(size),0) AS s FROM files WHERE user_id=?').get(uid).s; + if (usedBytes >= totalLimitMb * 1024 * 1024) + return res.status(400).json({ error: `Gesamtlimit von ${totalLimitMb} MB erreicht` }); getUpload().single('file')(req, res, err => { if (err) return res.status(400).json({ error: err.message }); if (!req.file) return res.status(400).json({ error: 'Keine Datei' }); @@ -200,9 +202,9 @@ router.get('/storage', authenticate, (req, res) => { const uid = req.user.id; const used = db.prepare('SELECT COALESCE(SUM(size),0) AS s FROM files WHERE user_id=?').get(uid).s; const count = db.prepare('SELECT COUNT(*) AS c FROM files WHERE user_id=?').get(uid).c; - const maxSizeMb = parseInt(getSetting('file_max_size_mb') || '50'); - const maxCount = parseInt(getSetting('file_max_count') || '20'); - res.json({ used, count, maxSizeMb, maxCount }); + const maxSizeMb = parseInt(getSetting('file_max_size_mb') || '50'); + const totalLimitMb = parseInt(getSetting('file_total_size_mb') || '500'); + res.json({ used, count, maxSizeMb, totalLimitMb }); }); router.get('/:id/download', authenticate, async (req, res) => { @@ -295,7 +297,7 @@ router.get('/settings', authenticate, requireAdmin, (req, res) => { res.json(obj); }); router.put('/settings', authenticate, requireAdmin, (req, res) => { - for (const key of ['file_max_size_mb','file_max_count','file_allowed_ext']) { + for (const key of ['file_max_size_mb','file_total_size_mb','file_allowed_ext']) { if (req.body[key] !== undefined) db.prepare('INSERT OR REPLACE INTO admin_settings (key,value) VALUES (?,?)').run(key, String(req.body[key])); } diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index c7f66f9..1b947a4 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -686,7 +686,7 @@ function BestellStats() {
@@ -1457,7 +1457,12 @@ function AdminPanel({ toast, mobile, user }) { )} {section === 'benutzer' && user?.role==='admin' && ( -
+
+ + + + +
)} {section === 'dashboard' && ( @@ -1468,9 +1473,6 @@ function AdminPanel({ toast, mobile, user }) { - {user?.role==='admin' && - - }
)} diff --git a/frontend/src/tools/dateien.jsx b/frontend/src/tools/dateien.jsx index c5a709a..156069c 100644 --- a/frontend/src/tools/dateien.jsx +++ b/frontend/src/tools/dateien.jsx @@ -284,15 +284,15 @@ export default function Dateien({ toast, mobile }) { border:'1px solid rgba(255,255,255,0.06)',borderRadius:8}}>
- {fmtSize(storage.used)} belegt · {storage.count}/{storage.maxCount} Dateien - max. {storage.maxSizeMb} MB pro Datei + {fmtSize(storage.used)} / {storage.totalLimitMb} MB belegt + max. {storage.maxSizeMb} MB pro Datei · {storage.count} Dateien
0.85 ? '#ff6b9d' : - storage.count/storage.maxCount > 0.6 ? '#ffe66d' : '#4ecdc4', + width:`${Math.min(100,(storage.used/(storage.totalLimitMb*1024*1024))*100)}%`, + background: storage.used/(storage.totalLimitMb*1024*1024) > 0.85 ? '#ff6b9d' : + storage.used/(storage.totalLimitMb*1024*1024) > 0.6 ? '#ffe66d' : '#4ecdc4', transition:'width 0.4s', }}/>
@@ -509,9 +509,9 @@ export default function Dateien({ toast, mobile }) { // ── Datei-Einstellungen (Admin) ─────────────────────────────────────────────── export function DateiSettings({ toast }) { - const [s, setS] = useState({file_max_size_mb:'50',file_max_count:'20',file_allowed_ext:'.pdf,.jpg,.jpeg,.png,.gif,.zip,.txt,.docx,.xlsx,.mp4,.stl,.3mf'}); + const [s, setS] = useState({file_max_size_mb:'50',file_total_size_mb:'500',file_allowed_ext:'.pdf,.jpg,.jpeg,.png,.gif,.zip,.txt,.docx,.xlsx,.mp4,.stl,.3mf'}); const [busy, setBusy] = useState(false); - useEffect(()=>{api('/tools/dateien/settings').then(setS).catch(()=>{});},[]); + useEffect(()=>{api('/tools/dateien/settings').then(d=>setS(prev=>({...prev,...d}))).catch(()=>{});},[]); const save = async()=>{ setBusy(true); try{await api('/tools/dateien/settings',{method:'PUT',body:s});toast('Gespeichert ✓');} @@ -520,12 +520,12 @@ export function DateiSettings({ toast }) { return (
- + setS(p=>({...p,file_max_size_mb:e.target.value}))} style={{...S.inp,fontSize:15}} min="1"/>
- - setS(p=>({...p,file_max_count:e.target.value}))} style={{...S.inp,fontSize:15}} min="1"/> + + setS(p=>({...p,file_total_size_mb:e.target.value}))} style={{...S.inp,fontSize:15}} min="1"/>