Files
Shifted/app/api/cart/add/route.ts
2026-02-10 01:14:19 +00:00

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 }
);
}
}