95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { Role } from "@prisma/client";
|
|
import { NextResponse } from "next/server";
|
|
import { prisma } from "../../../../../../lib/prisma";
|
|
import { requireAuth } from "../../../../../../lib/jwt";
|
|
|
|
export async function DELETE(
|
|
req: Request,
|
|
{ params }: { params: { id: string; imageId: string } },
|
|
) {
|
|
try {
|
|
const auth = await requireAuth(req);
|
|
const listing = await prisma.listing.findUnique({
|
|
where: { id: params.id, removedAt: null },
|
|
select: {
|
|
id: true,
|
|
ownerId: true,
|
|
status: true,
|
|
images: {
|
|
orderBy: { order: "asc" },
|
|
select: { id: true, isCover: true, order: true },
|
|
},
|
|
},
|
|
});
|
|
|
|
if (!listing) {
|
|
return NextResponse.json({ error: "Listing not found" }, { status: 404 });
|
|
}
|
|
|
|
const isOwner = listing.ownerId === auth.userId;
|
|
const isAdmin = auth.role === Role.ADMIN;
|
|
if (!isOwner && !isAdmin) {
|
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
|
}
|
|
|
|
const targetImage = listing.images.find((img) => img.id === params.imageId);
|
|
if (!targetImage) {
|
|
return NextResponse.json({ error: "Image not found" }, { status: 404 });
|
|
}
|
|
|
|
if (listing.images.length <= 1) {
|
|
return NextResponse.json(
|
|
{ error: "At least one image is required" },
|
|
{ status: 400 },
|
|
);
|
|
}
|
|
|
|
const remaining = listing.images.filter((img) => img.id !== params.imageId);
|
|
const newCoverId =
|
|
remaining.find((img) => img.isCover)?.id ?? remaining[0]?.id ?? null;
|
|
|
|
await prisma.$transaction([
|
|
prisma.listingImage.delete({ where: { id: params.imageId } }),
|
|
...remaining.map((img, idx) =>
|
|
prisma.listingImage.update({
|
|
where: { id: img.id },
|
|
data: {
|
|
order: idx + 1,
|
|
isCover: newCoverId ? img.id === newCoverId : img.isCover,
|
|
},
|
|
}),
|
|
),
|
|
]);
|
|
|
|
const updated = await prisma.listing.findUnique({
|
|
where: { id: listing.id },
|
|
select: {
|
|
images: {
|
|
orderBy: { order: "asc" },
|
|
select: {
|
|
id: true,
|
|
url: true,
|
|
altText: true,
|
|
order: true,
|
|
isCover: true,
|
|
size: true,
|
|
mimeType: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
return NextResponse.json({ ok: true, images: updated?.images ?? [] });
|
|
} catch (error: any) {
|
|
console.error("Delete listing image error", error);
|
|
if (String(error).includes("Unauthorized")) {
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
return NextResponse.json(
|
|
{ error: "Failed to delete image" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|
|
|
|
export const dynamic = "force-dynamic";
|