69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
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 });
|
|
}
|
|
}
|