feat: add delete order button to admin panel

DELETE endpoint + trash button (with confirm dialog) in expanded order row.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 08:51:19 +02:00
parent c7f5d36f56
commit f030e5e96e
2 changed files with 42 additions and 1 deletions
+29 -1
View File
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback } from 'react'
import Image from 'next/image'
import {
Download, RefreshCw, LogOut, Search, Package,
ChevronDown, Check, X, ShoppingBag, Truck, Users, Euro, Sheet,
ChevronDown, Check, X, ShoppingBag, Truck, Users, Euro, Sheet, Trash2,
} from 'lucide-react'
import clsx from 'clsx'
@@ -80,6 +80,7 @@ export default function AdminPage() {
const [statusFilter, setStatusFilter] = useState('ALL')
const [expandedId, setExpandedId] = useState<string | null>(null)
const [updatingId, setUpdatingId] = useState<string | null>(null)
const [deletingId, setDeletingId] = useState<string | null>(null)
const [syncing, setSyncing] = useState(false)
const [syncMsg, setSyncMsg] = useState('')
@@ -143,6 +144,25 @@ export default function AdminPage() {
}
}
async function deleteOrder(orderId: string, orderNumber: string) {
if (!confirm(`Segur que vols esborrar la comanda ${orderNumber}? Aquesta acció no es pot desfer.`)) return
setDeletingId(orderId)
try {
await fetch('/api/orders', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
'x-admin-password': password,
},
body: JSON.stringify({ id: orderId }),
})
setOrders((prev) => prev.filter((o) => o.id !== orderId))
setExpandedId(null)
} finally {
setDeletingId(null)
}
}
async function handleSyncSheets() {
setSyncing(true)
setSyncMsg('')
@@ -454,6 +474,14 @@ export default function AdminPage() {
</button>
))}
</div>
<button
onClick={() => deleteOrder(order.id, order.orderNumber)}
disabled={deletingId === order.id}
className="mt-4 flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-semibold border border-red-500/30 text-red-400 hover:bg-red-500/10 transition-colors disabled:opacity-50"
>
<Trash2 size={13} />
{deletingId === order.id ? 'Esborrant...' : 'Esborrar comanda'}
</button>
</div>
</div>
)}
+13
View File
@@ -51,6 +51,19 @@ export async function GET(req: NextRequest) {
return NextResponse.json({ orders })
}
// DELETE /api/orders — delete order by id
export async function DELETE(req: NextRequest) {
if (!checkAdmin(req)) {
return NextResponse.json({ error: 'No autoritzat' }, { status: 401 })
}
const { id } = await req.json()
if (!id) return NextResponse.json({ error: 'Falta id' }, { status: 400 })
await prisma.order.delete({ where: { id } })
return NextResponse.json({ ok: true })
}
// PATCH /api/orders — update order status
export async function PATCH(req: NextRequest) {
if (!checkAdmin(req)) {