Fix bugs and improve code quality
Build and Deploy / build-and-deploy (push) Has been cancelled

- Fix memory leak: revoke object URLs in TimelineUploadSection
- Fix broken timeline photo URLs in admin panel (/data/... → /api/files/...)
- Remove duplicate bad-word list in AI moderation function
- Add input validation for type/status params in media and contributions API
- Add bulk-approve button in admin for pending contributions
- Add PATCH endpoint for bulk-approving all pending contributions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
denshooter
2026-03-09 01:02:10 +01:00
parent 31dff10636
commit e3d4f7c96e
5 changed files with 85 additions and 24 deletions
+18 -2
View File
@@ -1138,7 +1138,7 @@ export default function AdminPage() {
{entry.media_filenames.split(',').slice(0, 3).map((filename, idx) => (
<img
key={idx}
src={`/data/uploads/photos/${filename.trim()}`}
src={`/api/files/${filename.trim()}`}
alt=""
className="w-10 h-10 object-cover rounded border border-warm-border"
/>
@@ -1608,7 +1608,23 @@ export default function AdminPage() {
</h2>
{/* Status Filter Tabs */}
<div className="flex gap-2 mb-6">
<div className="flex flex-wrap gap-2 mb-6">
{timelineContributions.filter(c => c.status === 'pending').length > 0 && (
<button
onClick={async () => {
if (!confirm(`Alle ${timelineContributions.filter(c => c.status === 'pending').length} ausstehenden Beiträge freigeben?`)) return
await fetch('/api/contributions', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'approve-all-pending' }),
})
loadData()
}}
className="px-4 py-2 rounded-lg text-sm font-lora bg-green-600 hover:bg-green-700 text-white transition-colors"
>
Alle ausstehenden freigeben ({timelineContributions.filter(c => c.status === 'pending').length})
</button>
)}
<button
onClick={() => setContributionFilter('review')}
className={`px-4 py-2 rounded-lg text-sm font-lora transition-colors ${