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

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