153 lines
4.5 KiB
TypeScript
153 lines
4.5 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { prisma } from "../../../../lib/prisma";
|
|
import { cookies } from "next/headers";
|
|
import { getServerSession } from "next-auth";
|
|
import { authOptions } from "../../../../lib/auth";
|
|
|
|
export async function POST(req: Request) {
|
|
try {
|
|
const body = await req.json();
|
|
const slug = body.slug as string;
|
|
const productId = body.productId as string;
|
|
const priceId = body.priceId as string;
|
|
const name = body.name as string;
|
|
const unitAmount = Number(body.unitAmount);
|
|
const currency = body.currency as string;
|
|
const quantity = Number(body.quantity) || 1;
|
|
|
|
if (
|
|
!slug ||
|
|
!productId ||
|
|
!priceId ||
|
|
!name ||
|
|
!Number.isFinite(unitAmount) ||
|
|
!currency
|
|
) {
|
|
return NextResponse.json(
|
|
{ error: "Missing required cart fields." },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const store = await prisma.store.findUnique({ where: { slug } });
|
|
if (!store) {
|
|
return NextResponse.json({ error: "Store not found." }, { status: 404 });
|
|
}
|
|
|
|
const session = await getServerSession(authOptions);
|
|
const cookieStore = cookies();
|
|
let sessionId = cookieStore.get("sf_session")?.value;
|
|
const createdNew = !sessionId;
|
|
if (!sessionId) sessionId = crypto.randomUUID();
|
|
|
|
const sessionCart = await prisma.cart.findUnique({
|
|
where: { storeId_sessionId: { storeId: store.id, sessionId } },
|
|
});
|
|
|
|
let cart;
|
|
if (session?.user?.email) {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: session.user.email },
|
|
});
|
|
if (!user) {
|
|
return NextResponse.json({ error: "User not found." }, { status: 404 });
|
|
}
|
|
const userCart = await prisma.cart.findUnique({
|
|
where: { storeId_userId: { storeId: store.id, userId: user.id } },
|
|
});
|
|
|
|
if (!userCart) {
|
|
if (sessionCart) {
|
|
cart = await prisma.cart.update({
|
|
where: { id: sessionCart.id },
|
|
data: { userId: user.id },
|
|
});
|
|
} else {
|
|
cart = await prisma.cart.create({
|
|
data: { storeId: store.id, userId: user.id, sessionId },
|
|
});
|
|
}
|
|
} else if (sessionCart && sessionCart.id !== userCart.id) {
|
|
const sessionItems = await prisma.cartItem.findMany({
|
|
where: { cartId: sessionCart.id },
|
|
});
|
|
for (const item of sessionItems) {
|
|
const existing = await prisma.cartItem.findFirst({
|
|
where: { cartId: userCart.id, priceId: item.priceId },
|
|
});
|
|
if (existing) {
|
|
await prisma.cartItem.update({
|
|
where: { id: existing.id },
|
|
data: { quantity: existing.quantity + item.quantity },
|
|
});
|
|
} else {
|
|
await prisma.cartItem.create({
|
|
data: {
|
|
cartId: userCart.id,
|
|
productId: item.productId,
|
|
priceId: item.priceId,
|
|
name: item.name,
|
|
unitAmount: item.unitAmount,
|
|
currency: item.currency,
|
|
quantity: item.quantity,
|
|
},
|
|
});
|
|
}
|
|
}
|
|
await prisma.cart.delete({ where: { id: sessionCart.id } });
|
|
cart = await prisma.cart.update({
|
|
where: { id: userCart.id },
|
|
data: { sessionId },
|
|
});
|
|
} else if (userCart.sessionId !== sessionId) {
|
|
cart = await prisma.cart.update({
|
|
where: { id: userCart.id },
|
|
data: { sessionId },
|
|
});
|
|
} else {
|
|
cart = userCart;
|
|
}
|
|
} else {
|
|
cart =
|
|
sessionCart ??
|
|
(await prisma.cart.create({ data: { storeId: store.id, sessionId } }));
|
|
}
|
|
|
|
const existing = await prisma.cartItem.findFirst({
|
|
where: { cartId: cart.id, priceId },
|
|
});
|
|
|
|
const item = existing
|
|
? await prisma.cartItem.update({
|
|
where: { id: existing.id },
|
|
data: { quantity: existing.quantity + quantity },
|
|
})
|
|
: await prisma.cartItem.create({
|
|
data: {
|
|
cartId: cart.id,
|
|
productId,
|
|
priceId,
|
|
name,
|
|
unitAmount,
|
|
currency,
|
|
quantity,
|
|
},
|
|
});
|
|
|
|
const res = NextResponse.json({ item });
|
|
if (createdNew) {
|
|
res.cookies.set("sf_session", sessionId, {
|
|
httpOnly: true,
|
|
sameSite: "lax",
|
|
path: "/",
|
|
});
|
|
}
|
|
return res;
|
|
} catch (err: any) {
|
|
return NextResponse.json(
|
|
{ error: err?.message || "Failed to add to cart." },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|