"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { formatPrice } from "@/data/sample";
import { useAuth } from "@/lib/auth";
import { useCart } from "@/lib/cart";
import { customerLoginUrl } from "@/lib/customer-auth";
type Address = {
id: string;
label?: string;
province: string;
city: string;
address: string;
postalCode?: string;
landline?: string;
};
type PaymentMethods = {
cash?: boolean;
transfer?: boolean;
pos?: boolean;
ePayment?: {
enabled?: boolean;
defaultGateway?: string;
gateways?: string[];
};
};
export function CheckoutPage() {
const router = useRouter();
const { isAuthenticated, ready: authReady, getAccessToken } = useAuth();
const { items, total, ready: cartReady } = useCart();
const [addresses, setAddresses] = useState
([]);
const [methods, setMethods] = useState(null);
const [addressId, setAddressId] = useState("");
const [paymentType, setPaymentType] = useState<"cash" | "transfer" | "e_payment_gate">("cash");
const [gatewayType, setGatewayType] = useState("zarinpal");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [shipping, setShipping] = useState({
province: "",
city: "",
address: "",
postalCode: "",
landline: "",
});
useEffect(() => {
if (!authReady) return;
if (!isAuthenticated) {
window.location.href = customerLoginUrl("/checkout");
}
}, [authReady, isAuthenticated]);
useEffect(() => {
const token = getAccessToken();
if (!token) return;
Promise.all([
fetch("/api/addresses", { headers: { Authorization: `Bearer ${token}` } }).then((r) =>
r.ok ? r.json() : { items: [] },
),
fetch("/api/payments/methods", { headers: { Authorization: `Bearer ${token}` } }).then((r) =>
r.ok ? r.json() : null,
),
]).then(([addressRes, methodsRes]) => {
const nextAddresses = (addressRes.items ?? []) as Address[];
setAddresses(nextAddresses);
if (nextAddresses[0]) setAddressId(nextAddresses[0].id);
const nextMethods = (methodsRes ?? methodsRes?.methods ?? methodsRes) as PaymentMethods;
setMethods(nextMethods);
if (nextMethods?.ePayment?.enabled) {
setPaymentType("e_payment_gate");
setGatewayType(nextMethods.ePayment.defaultGateway ?? nextMethods.ePayment.gateways?.[0] ?? "zarinpal");
} else if (nextMethods?.cash) {
setPaymentType("cash");
} else if (nextMethods?.transfer) {
setPaymentType("transfer");
}
});
}, [getAccessToken, isAuthenticated]);
const onSubmit = async (event: React.FormEvent) => {
event.preventDefault();
const token = getAccessToken();
if (!token) return;
setLoading(true);
setError(null);
const payload: Record = {
payment: { type: paymentType },
};
if (addressId) {
payload.addressId = addressId;
} else {
payload.shippingAddress = shipping;
}
if (paymentType === "e_payment_gate") {
payload.payment = { type: paymentType, gatewayType };
payload.returnUrl = `${window.location.origin}/checkout/complete`;
}
try {
const res = await fetch("/api/cart/checkout", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(payload),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error ?? "ثبت سفارش ناموفق بود");
const redirect = data.payment?.redirect;
if (redirect?.url) {
if (redirect.method === "POST" && redirect.fields) {
const form = document.createElement("form");
form.method = "POST";
form.action = redirect.url;
for (const [key, value] of Object.entries(redirect.fields as Record)) {
const input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = value;
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
return;
}
window.location.href = redirect.url;
return;
}
router.push(`/checkout/complete?orderId=${data.order?.id ?? ""}`);
} catch (err) {
setError(err instanceof Error ? err.message : "خطا در ثبت سفارش");
} finally {
setLoading(false);
}
};
if (!authReady || !cartReady || !isAuthenticated) {
return در حال بارگذاری...
;
}
if (items.length === 0) {
return (
سبد خرید شما خالی است
بازگشت به فروشگاه
);
}
return (
);
}