90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
"use server";
|
|
|
|
import { redirect } from "next/navigation";
|
|
import { z } from "zod";
|
|
import { db } from "@/lib/db";
|
|
import { auth } from "@/lib/auth";
|
|
import { getCart, cartTotal, setCartItems } from "@/lib/cart";
|
|
|
|
const CheckoutSchema = z.object({
|
|
name: z.string().min(2, "Zadej jméno a příjmení"),
|
|
email: z.string().email("Neplatný e-mail"),
|
|
phone: z.string().optional(),
|
|
street: z.string().min(3, "Zadej ulici a číslo popisné"),
|
|
city: z.string().min(2, "Zadej město"),
|
|
zip: z.string().regex(/^\d{3}\s?\d{2}$/, "Neplatné PSČ (např. 110 00)"),
|
|
country: z.string().default("CZ"),
|
|
note: z.string().optional(),
|
|
});
|
|
|
|
export type CheckoutFormState = {
|
|
error?: string;
|
|
fieldErrors?: Record<string, string[]>;
|
|
};
|
|
|
|
export async function createOrder(
|
|
_prev: CheckoutFormState,
|
|
formData: FormData
|
|
): Promise<CheckoutFormState> {
|
|
const parsed = CheckoutSchema.safeParse({
|
|
name: formData.get("name"),
|
|
email: formData.get("email"),
|
|
phone: formData.get("phone"),
|
|
street: formData.get("street"),
|
|
city: formData.get("city"),
|
|
zip: formData.get("zip"),
|
|
country: formData.get("country") || "CZ",
|
|
note: formData.get("note"),
|
|
});
|
|
|
|
if (!parsed.success) {
|
|
return { fieldErrors: parsed.error.flatten().fieldErrors };
|
|
}
|
|
|
|
const items = await getCart();
|
|
if (items.length === 0) {
|
|
return { error: "Košík je prázdný." };
|
|
}
|
|
|
|
const session = await auth();
|
|
const total = cartTotal(items);
|
|
|
|
const order = await db.order.create({
|
|
data: {
|
|
userId: session?.user?.id ?? null,
|
|
guestEmail: session ? null : parsed.data.email,
|
|
status: "PENDING",
|
|
totalAmount: total,
|
|
shippingName: parsed.data.name,
|
|
shippingEmail: parsed.data.email,
|
|
shippingPhone: parsed.data.phone || null,
|
|
shippingStreet: parsed.data.street,
|
|
shippingCity: parsed.data.city,
|
|
shippingZip: parsed.data.zip.replace(/\s/g, ""),
|
|
shippingCountry: parsed.data.country,
|
|
items: {
|
|
create: items.map((item) => ({
|
|
productId: item.variant.product.id,
|
|
variantId: item.variantId,
|
|
quantity: item.quantity,
|
|
unitPrice: item.variant.price,
|
|
})),
|
|
},
|
|
},
|
|
});
|
|
|
|
// Vyprázdnit košík
|
|
await setCartItems([]);
|
|
|
|
redirect(`/objednavka/${order.id}`);
|
|
}
|
|
|
|
// ── Admin: změna stavu objednávky ─────────────────────────────────────────
|
|
|
|
export async function updateOrderStatus(id: string, status: string) {
|
|
await db.order.update({
|
|
where: { id },
|
|
data: { status: status as never },
|
|
});
|
|
}
|