77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { cookies } from "next/headers";
|
|
import { db } from "@/lib/db";
|
|
|
|
export const CART_COOKIE = "bistrousky_cart";
|
|
|
|
export interface CartItem {
|
|
variantId: string;
|
|
quantity: number;
|
|
}
|
|
|
|
// ── Čtení / zápis cookie ──────────────────────────────────────────────────
|
|
|
|
export async function getCartItems(): Promise<CartItem[]> {
|
|
const store = await cookies();
|
|
const raw = store.get(CART_COOKIE)?.value;
|
|
if (!raw) return [];
|
|
try {
|
|
return JSON.parse(raw) as CartItem[];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export async function setCartItems(items: CartItem[]) {
|
|
const store = await cookies();
|
|
store.set(CART_COOKIE, JSON.stringify(items), {
|
|
httpOnly: true,
|
|
sameSite: "lax",
|
|
path: "/",
|
|
maxAge: 60 * 60 * 24 * 30, // 30 dní
|
|
});
|
|
}
|
|
|
|
// ── Košík s daty z DB ─────────────────────────────────────────────────────
|
|
|
|
export interface CartItemFull {
|
|
variantId: string;
|
|
quantity: number;
|
|
variant: {
|
|
id: string;
|
|
name: string;
|
|
price: number;
|
|
stock: number;
|
|
product: {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
image: string | null;
|
|
};
|
|
};
|
|
}
|
|
|
|
export async function getCart(): Promise<CartItemFull[]> {
|
|
const items = await getCartItems();
|
|
if (items.length === 0) return [];
|
|
|
|
const variantIds = items.map((i) => i.variantId);
|
|
const variants = await db.productVariant.findMany({
|
|
where: { id: { in: variantIds } },
|
|
include: {
|
|
product: { select: { id: true, name: true, slug: true, image: true } },
|
|
},
|
|
});
|
|
|
|
return items
|
|
.map((item) => {
|
|
const variant = variants.find((v) => v.id === item.variantId);
|
|
if (!variant) return null;
|
|
return { variantId: item.variantId, quantity: item.quantity, variant };
|
|
})
|
|
.filter(Boolean) as CartItemFull[];
|
|
}
|
|
|
|
export function cartTotal(items: CartItemFull[]): number {
|
|
return items.reduce((sum, item) => sum + item.variant.price * item.quantity, 0);
|
|
}
|