"use client"; import { useState, useEffect } from "react"; import { useRouter } from "next/navigation"; import Link from "next/link"; import Image from "next/image"; import { useTranslations, useLocale } from "next-intl"; import Header from "@/components/layout/Header"; import Footer from "@/components/layout/Footer"; import { useSaleorCheckoutStore } from "@/stores/saleorCheckoutStore"; import { formatPrice } from "@/lib/saleor"; import { saleorClient } from "@/lib/saleor/client"; import { CHECKOUT_SHIPPING_ADDRESS_UPDATE, CHECKOUT_BILLING_ADDRESS_UPDATE, CHECKOUT_COMPLETE, } from "@/lib/saleor/mutations/Checkout"; import type { Checkout } from "@/types/saleor"; interface ShippingAddressUpdateResponse { checkoutShippingAddressUpdate?: { checkout?: Checkout; errors?: Array<{ message: string }>; }; } interface BillingAddressUpdateResponse { checkoutBillingAddressUpdate?: { checkout?: Checkout; errors?: Array<{ message: string }>; }; } interface CheckoutCompleteResponse { checkoutComplete?: { order?: { number: string }; errors?: Array<{ message: string }>; }; } interface AddressForm { firstName: string; lastName: string; streetAddress1: string; streetAddress2: string; city: string; postalCode: string; phone: string; } export default function CheckoutPage() { const t = useTranslations("Checkout"); const locale = useLocale(); const router = useRouter(); const { checkout, refreshCheckout, getLines, getTotal } = useSaleorCheckoutStore(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [orderComplete, setOrderComplete] = useState(false); const [orderNumber, setOrderNumber] = useState(null); const [sameAsShipping, setSameAsShipping] = useState(true); const [shippingAddress, setShippingAddress] = useState({ firstName: "", lastName: "", streetAddress1: "", streetAddress2: "", city: "", postalCode: "", phone: "", }); const [billingAddress, setBillingAddress] = useState({ firstName: "", lastName: "", streetAddress1: "", streetAddress2: "", city: "", postalCode: "", phone: "", }); const lines = getLines(); const total = getTotal(); useEffect(() => { if (!checkout) { refreshCheckout(); } }, [checkout, refreshCheckout]); const handleShippingChange = (field: keyof AddressForm, value: string) => { setShippingAddress((prev) => ({ ...prev, [field]: value })); if (sameAsShipping) { setBillingAddress((prev) => ({ ...prev, [field]: value })); } }; const handleBillingChange = (field: keyof AddressForm, value: string) => { setBillingAddress((prev) => ({ ...prev, [field]: value })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!checkout) { setError(t("errorNoCheckout")); return; } setIsLoading(true); setError(null); try { const shippingResult = await saleorClient.mutate({ mutation: CHECKOUT_SHIPPING_ADDRESS_UPDATE, variables: { checkoutId: checkout.id, shippingAddress: { ...shippingAddress, country: "RS", }, }, }); if (shippingResult.data?.checkoutShippingAddressUpdate?.errors && shippingResult.data.checkoutShippingAddressUpdate.errors.length > 0) { throw new Error(shippingResult.data.checkoutShippingAddressUpdate.errors[0].message); } const billingResult = await saleorClient.mutate({ mutation: CHECKOUT_BILLING_ADDRESS_UPDATE, variables: { checkoutId: checkout.id, billingAddress: { ...billingAddress, country: "RS", }, }, }); if (billingResult.data?.checkoutBillingAddressUpdate?.errors && billingResult.data.checkoutBillingAddressUpdate.errors.length > 0) { throw new Error(billingResult.data.checkoutBillingAddressUpdate.errors[0].message); } const completeResult = await saleorClient.mutate({ mutation: CHECKOUT_COMPLETE, variables: { checkoutId: checkout.id, }, }); if (completeResult.data?.checkoutComplete?.errors && completeResult.data.checkoutComplete.errors.length > 0) { throw new Error(completeResult.data.checkoutComplete.errors[0].message); } const order = completeResult.data?.checkoutComplete?.order; if (order) { setOrderNumber(order.number); setOrderComplete(true); } else { throw new Error(t("errorCreatingOrder")); } } catch (err: unknown) { const errorMessage = err instanceof Error ? err.message : null; setError(errorMessage || t("errorOccurred")); } finally { setIsLoading(false); } }; if (orderComplete) { return ( <>

{t("orderConfirmed")}

{t("thankYou")}

{orderNumber && (

{t("orderNumber")}

#{orderNumber}

)}

{t("confirmationEmail")}

{t("continueShoppingBtn")}
); } return ( <>

{t("checkout")}

{error && (
{error}
)}

{t("shippingAddress")}

handleShippingChange("firstName", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("lastName", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("streetAddress1", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("streetAddress2", e.target.value)} placeholder={t("streetAddressOptional")} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("city", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("postalCode", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />
handleShippingChange("phone", e.target.value)} className="w-full border border-border px-4 py-2 rounded" />

{t("orderSummary")}

{lines.length === 0 ? (

{t("yourCartEmpty")}

) : ( <>
{lines.map((line) => (
{line.variant.product.media[0]?.url && ( {line.variant.product.name} )}

{line.variant.product.name}

{t("qty")}: {line.quantity}

{formatPrice(line.totalPrice.gross.amount)}

))}
{t("subtotal")} {formatPrice(checkout?.subtotalPrice?.gross?.amount || 0)}
{t("total")} {formatPrice(total)}
)}
); }