132 lines
4.0 KiB
TypeScript
132 lines
4.0 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 GET(req: Request) {
|
|
try {
|
|
const { searchParams } = new URL(req.url);
|
|
const slug = searchParams.get("slug");
|
|
|
|
if (!slug) {
|
|
return NextResponse.json({ error: "slug is required." }, { 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 = sessionId
|
|
? await prisma.cart.findUnique({
|
|
where: { storeId_sessionId: { storeId: store.id, sessionId } },
|
|
include: { items: true },
|
|
})
|
|
: null;
|
|
|
|
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 });
|
|
}
|
|
|
|
let userCart = await prisma.cart.findUnique({
|
|
where: { storeId_userId: { storeId: store.id, userId: user.id } },
|
|
include: { items: true },
|
|
});
|
|
|
|
if (!userCart) {
|
|
if (sessionCart) {
|
|
userCart = await prisma.cart.update({
|
|
where: { id: sessionCart.id },
|
|
data: { userId: user.id },
|
|
include: { items: true },
|
|
});
|
|
} else {
|
|
userCart = await prisma.cart.create({
|
|
data: { storeId: store.id, userId: user.id, sessionId },
|
|
include: { items: true },
|
|
});
|
|
}
|
|
} else if (sessionCart && sessionCart.id !== userCart.id) {
|
|
for (const item of sessionCart.items) {
|
|
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 } });
|
|
userCart = await prisma.cart.update({
|
|
where: { id: userCart.id },
|
|
data: { sessionId },
|
|
include: { items: true },
|
|
});
|
|
} else if (userCart.sessionId !== sessionId) {
|
|
userCart = await prisma.cart.update({
|
|
where: { id: userCart.id },
|
|
data: { sessionId },
|
|
include: { items: true },
|
|
});
|
|
}
|
|
|
|
const res = NextResponse.json({ cart: userCart });
|
|
if (createdNew) {
|
|
res.cookies.set("sf_session", sessionId, {
|
|
httpOnly: true,
|
|
sameSite: "lax",
|
|
path: "/",
|
|
});
|
|
}
|
|
return res;
|
|
}
|
|
|
|
const cart =
|
|
sessionCart ??
|
|
(await prisma.cart.create({
|
|
data: { storeId: store.id, sessionId },
|
|
include: { items: true },
|
|
}));
|
|
|
|
const res = NextResponse.json({ cart });
|
|
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 load cart." },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|