diff --git a/app/(manage)/manage/benchmarks/benchmarks-client.tsx b/app/(manage)/manage/benchmarks/benchmarks-client.tsx index e304de5..956be3b 100644 --- a/app/(manage)/manage/benchmarks/benchmarks-client.tsx +++ b/app/(manage)/manage/benchmarks/benchmarks-client.tsx @@ -110,7 +110,7 @@ export function BenchmarksClient() { const [statusFilter, setStatusFilter] = useState("all") const [actionLoading, setActionLoading] = useState>({}) const [confirmAction, setConfirmAction] = useState< - | { type: "verify" | "remove" | "restore"; entry: PerformanceEntry } + | { type: "verify" | "remove" | "restore" | "hardDelete"; entry: PerformanceEntry } | null >(null) const [removeReason, setRemoveReason] = useState("") @@ -224,6 +224,22 @@ export function BenchmarksClient() { } } + const handleHardDelete = async (entry: PerformanceEntry) => { + setActionLoading((prev) => ({ ...prev, [entry.id]: true })) + try { + const res = await fetch(`/api/admin/performance/${entry.id}/hard-delete`, { + method: "DELETE", + }) + if (res.ok) { + setEntries((prev) => prev.filter((e) => e.id !== entry.id)) + setTotal((prev) => Math.max(0, prev - 1)) + setConfirmAction(null) + } + } finally { + setActionLoading((prev) => ({ ...prev, [entry.id]: false })) + } + } + const handleRestore = async (entry: PerformanceEntry) => { setActionLoading((prev) => ({ ...prev, [entry.id]: true })) try { @@ -281,7 +297,8 @@ export function BenchmarksClient() { {/* Table */}
- +
+
@@ -459,6 +485,7 @@ export function BenchmarksClient() { )}
@@ -452,6 +469,15 @@ export function BenchmarksClient() { Restore )} +
+
{/* Pagination */} @@ -596,6 +623,37 @@ export function BenchmarksClient() { )} + + {confirmAction.type === "hardDelete" && ( + <> +

+ ⚠️ Permanent Delete +

+

+ This will permanently delete this benchmark entry. This action cannot be undone. +

+
+ + +
+ + )} )} diff --git a/lib/api/admin-performance.ts b/lib/api/admin-performance.ts index 946527c..d7631cb 100644 --- a/lib/api/admin-performance.ts +++ b/lib/api/admin-performance.ts @@ -226,6 +226,36 @@ export const adminPerformanceRoutes = new Elysia({ prefix: "/admin" }) ), }, ) + .delete( + "/performance/:id/hard-delete", + async ({ params, request, set }) => { + const guard = await requireAdmin(request.headers) + if (!guard.ok) { + set.status = guard.status + return { error: guard.error } + } + + const [entry] = await db + .select() + .from(performanceEntries) + .where(eq(performanceEntries.id, params.id)) + .limit(1) + + if (!entry) { + set.status = 404 + return { error: "Performance entry not found" } + } + + await db + .delete(performanceEntries) + .where(eq(performanceEntries.id, params.id)) + + return { success: true } + }, + { + params: t.Object({ id: t.String() }), + }, + ) .patch( "/performance/:id/restore", async ({ params, request, set }) => {