feat: implement full CRUD functionality for projects with image upload support and admin dashboard management
This commit is contained in:
68
src/app/api/admin/projects/route.ts
Normal file
68
src/app/api/admin/projects/route.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { prisma } from "@/core/db/prisma";
|
||||
import { uploadFileLocally } from "@/core/storage/local";
|
||||
import { verifySession } from "@/core/security/session";
|
||||
import { projectSchema } from "@/features/projects/project-schema";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const session = await verifySession();
|
||||
if (!session) {
|
||||
return NextResponse.json({ success: false, message: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
try {
|
||||
const formData = await req.formData();
|
||||
|
||||
const data = {
|
||||
title: formData.get("title") as string,
|
||||
slug: formData.get("slug") as string,
|
||||
description: formData.get("description") as string,
|
||||
category: formData.get("category") as string,
|
||||
repoUrl: formData.get("repoUrl") as string,
|
||||
liveUrl: formData.get("liveUrl") as string,
|
||||
isPublished: formData.get("isPublished") === "true" || formData.get("isPublished") === "on",
|
||||
image: formData.get("image") as File | null,
|
||||
};
|
||||
|
||||
const validation = projectSchema.safeParse(data);
|
||||
if (!validation.success) {
|
||||
return NextResponse.json({ success: false, message: validation.error.issues[0].message }, { status: 400 });
|
||||
}
|
||||
|
||||
let imageUrl: string | undefined = undefined;
|
||||
if (data.image && data.image.size > 0 && data.image.name) {
|
||||
try {
|
||||
imageUrl = await uploadFileLocally(data.image);
|
||||
} catch (e: any) {
|
||||
console.error("Local upload error:", e);
|
||||
return NextResponse.json({ success: false, message: "Failed to upload image locally." }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
const project = await prisma.project.create({
|
||||
data: {
|
||||
title: validation.data.title,
|
||||
slug: validation.data.slug,
|
||||
description: validation.data.description,
|
||||
category: validation.data.category,
|
||||
repoUrl: validation.data.repoUrl || null,
|
||||
liveUrl: validation.data.liveUrl || null,
|
||||
isPublished: validation.data.isPublished,
|
||||
imageUrl: imageUrl,
|
||||
},
|
||||
});
|
||||
|
||||
revalidatePath("/admin/dashboard/projects");
|
||||
revalidatePath("/admin/dashboard");
|
||||
revalidatePath("/");
|
||||
|
||||
return NextResponse.json({ success: true, project });
|
||||
} catch (error: any) {
|
||||
console.error("API Error (Create Project):", error);
|
||||
if (error?.code === "P2002") {
|
||||
return NextResponse.json({ success: false, message: "Project slug already exists" }, { status: 400 });
|
||||
}
|
||||
return NextResponse.json({ success: false, message: "Failed to create project" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user