import { adminDeleteUploadAction, adminExtendUploadAction, adminLogoutAction, adminSaveUploadToPathAction, } from '@/src/lib/actions.js'; import { all, get, runCleanupIfNeeded } from '@/src/lib/db.js'; import { sharedLinkName } from '@/src/lib/files.js'; import { formatBytes, formatCountdown, formatTimestamp, parseLogDetail, readSearchParam, } from '@/src/lib/format.js'; import { ensureCsrfToken, requireAdminUser } from '@/src/lib/security.js'; import { CopyLinkButton } from '../../_components/copy-link-button.js'; import { StatusMessage } from '../../_components/status-message.js'; export const dynamic = 'force-dynamic'; export default async function AdminDashboardPage({ searchParams }) { await runCleanupIfNeeded(); await requireAdminUser(); const csrfToken = await ensureCsrfToken(); const [ activeCount, activeBytes, distinctOwners, totalUploads, totalDownloads, totalDeletes, lastCleanup, recentLogs, allUploads, uploadRequests, ] = await Promise.all([ get('SELECT COUNT(*) AS count FROM uploads'), get('SELECT COALESCE(SUM(size_bytes), 0) AS total FROM uploads'), get('SELECT COUNT(DISTINCT owner) AS count FROM uploads'), get('SELECT COUNT(*) AS count FROM admin_logs WHERE event = ?', ['upload']), get('SELECT COALESCE(SUM(downloads), 0) AS count FROM uploads'), get('SELECT COUNT(*) AS count FROM admin_logs WHERE event IN (?, ?, ?)', [ 'delete', 'cleanup', 'admin_delete', ]), get('SELECT MAX(created_at) AS ts FROM admin_logs WHERE event = ?', ['cleanup']), all( 'SELECT event, owner, detail, created_at, ip, user_agent FROM admin_logs ORDER BY created_at DESC LIMIT 250' ), all( 'SELECT id, owner, original_name, stored_name, size_bytes, uploaded_at, expires_at FROM uploads ORDER BY uploaded_at DESC LIMIT 500' ), all( `SELECT id, owner, note, created_at, expires_at, completed_at, upload_id, uploaded_original_name, uploaded_size_bytes FROM upload_requests ORDER BY created_at DESC LIMIT 500` ), ]); const resolvedSearchParams = await searchParams; const error = readSearchParam(resolvedSearchParams, 'error'); const success = readSearchParam(resolvedSearchParams, 'success'); const requestedTab = readSearchParam(resolvedSearchParams, 'tab'); const activeTab = ['stats', 'uploads', 'requests', 'logs'].includes(requestedTab) ? requestedTab : 'stats'; return (

Adminübersicht

Metriken, Ereignisse und direkte Eingriffe in Uploads.

Dateimanager Benutzer verwalten
{activeTab === 'stats' ? (

Statistiken

Aktive Uploads {activeCount?.count || 0}
Aktive Dateigröße {formatBytes(activeBytes?.total || 0)}
Aktive Nutzer {distinctOwners?.count || 0}
Uploads gesamt {totalUploads?.count || 0}
Downloads gesamt {totalDownloads?.count || 0}
Löschungen gesamt {totalDeletes?.count || 0}
Letztes Cleanup {lastCleanup?.ts ? formatTimestamp(lastCleanup.ts) : '-'}
) : null} {activeTab === 'uploads' ? (

Aktuelle Uploads

{allUploads.length === 0 ? (

Noch keine Uploads vorhanden.

) : (
{allUploads.map((item) => { const shareName = sharedLinkName(item.stored_name); const sharePath = `/_share/${encodeURIComponent(shareName)}`; return ( ); })}
Nutzer Datei Größe Hochgeladen Ablauf Aktionen
{item.owner} {item.original_name}
{item.stored_name}
{formatBytes(item.size_bytes)} {formatTimestamp(item.uploaded_at)}
{formatTimestamp(item.expires_at)}
Noch {formatCountdown(item.expires_at)}
Aktionen
)}
) : null} {activeTab === 'requests' ? (

Upload-Anfragen

{uploadRequests.length === 0 ? (

Keine Upload-Anfragen vorhanden.

) : (
{uploadRequests.map((entry) => { const isCompleted = Number(entry.completed_at || 0) > 0; const isExpired = !isCompleted && Number(entry.expires_at || 0) <= Date.now(); const requestPath = `/_request/${encodeURIComponent(entry.id)}`; return ( ); })}
Anfrage Nutzer Status Erstellt Ablauf Datei Aktionen
{entry.id} {entry.note ?
{entry.note}
: null}
{entry.owner} {isCompleted ? 'Abgeschlossen' : isExpired ? 'Abgelaufen' : 'Offen'} {formatTimestamp(entry.created_at)} {formatTimestamp(entry.expires_at)} {entry.uploaded_original_name ? ( <> {entry.uploaded_original_name}
{formatBytes(entry.uploaded_size_bytes || 0)}
) : ( - )}
Aktionen
Öffnen {entry.upload_id ? (
) : null}
)}
) : null} {activeTab === 'logs' ? (

Letzte Ereignisse

{recentLogs.length === 0 ? (

Keine Logs vorhanden.

) : (
{recentLogs.map((entry, index) => { const details = parseLogDetail(entry.detail); return ( ); })}
Zeit Event Nutzer IP Details User-Agent
{formatTimestamp(entry.created_at)} {entry.event} {entry.owner || '-'} {entry.ip || '-'} {details.length === 0 ? ( - ) : (
{details.map((detail) => (
{detail.key}: {detail.value}
))}
)}
{entry.user_agent || '-'}
)}
) : null}
); }