amazon-clone / apps /web /src /components /AddToCartButton.tsx
hyungjoochae's picture
Upload folder using huggingface_hub
321a7a2 verified
"use client";
import { useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { useState } from "react";
type Props = {
productId: string;
variantId?: string | null;
quantity?: number;
configuration?: Record<string, unknown>;
className?: string;
children?: ReactNode;
redirectToCart?: boolean;
};
export function AddToCartButton({
productId,
variantId,
quantity = 1,
configuration = {},
className,
children = "Add to cart",
redirectToCart = false,
}: Props) {
const router = useRouter();
const [loading, setLoading] = useState(false);
async function ensureSession() {
await fetch("/api/auth/demo", { cache: "no-store" });
}
return (
<button
type="button"
disabled={loading}
onClick={async () => {
setLoading(true);
try {
await ensureSession();
const r = await fetch("/api/cart/items", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
product_id: productId,
variant_id: variantId ?? null,
quantity,
configuration,
}),
});
if (!r.ok) throw new Error("add-to-cart failed");
window.dispatchEvent(new Event("cart:changed"));
if (redirectToCart) router.push("/cart");
} catch {
// keep UI calm; cart page can surface details later
} finally {
setLoading(false);
}
}}
className={className}
aria-busy={loading}
>
{loading ? "Adding…" : children}
</button>
);
}