import { useState } from "react"; import { toast } from "sonner"; import { Link, useNavigate } from "react-router-dom"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { Badge } from "@/components/ui/badge"; import { Check, CreditCard, MapPin, ClipboardList, ArrowLeft, ArrowRight, Lock } from "lucide-react"; import Header from "@/components/Header"; import Footer from "@/components/Footer"; import { useCart } from "@/lib/cart-context"; import { useSaasMutation } from "@/hooks/use-tygarun"; const steps = [ { num: 1, label: "Shipping", icon: MapPin }, { num: 2, label: "Payment", icon: CreditCard }, { num: 3, label: "Review", icon: ClipboardList }, ]; export default function CheckoutPage() { const [step, setStep] = useState(1); const [errors, setErrors] = useState>({}); const { items, total, clearCart } = useCart(); const navigate = useNavigate(); const { mutate: createCheckout, loading: placingOrder } = useSaasMutation("billing", "/checkout"); const [shipping, setShipping] = useState({ firstName: "", lastName: "", email: "", address: "", city: "", state: "", zip: "", }); const [payment, setPayment] = useState({ cardNumber: "", expiry: "", cvv: "", cardholder: "", }); const shippingCost = total >= 100 ? 0 : 12.99; const tax = total * 0.08; const grandTotal = total + shippingCost + tax; const validateShipping = () => { const e: Record = {}; if (!shipping.firstName.trim()) e.firstName = "First name is required"; if (!shipping.lastName.trim()) e.lastName = "Last name is required"; if (!shipping.email.includes("@")) e.email = "Valid email is required"; if (!shipping.address.trim()) e.address = "Address is required"; if (!shipping.city.trim()) e.city = "City is required"; if (!shipping.zip.trim()) e.zip = "ZIP code is required"; setErrors(e); return Object.keys(e).length === 0; }; const validatePayment = () => { const e: Record = {}; if (payment.cardNumber.replace(/\s/g, "").length < 16) e.cardNumber = "Enter a valid 16-digit card number"; if (!payment.expiry.trim()) e.expiry = "Expiry date is required"; if (payment.cvv.length < 3) e.cvv = "CVV must be at least 3 digits"; setErrors(e); return Object.keys(e).length === 0; }; const handlePlaceOrder = async () => { try { const res = await createCheckout({ amount: Math.round(grandTotal * 100), email: shipping.email, items: items.map((it) => ({ id: it.id, name: it.name, quantity: it.quantity, priceCents: Math.round(it.price * 100) })), }); if (res?.url && res.url.indexOf("#") !== 0) { window.location.href = res.url; return; } toast.success("Order placed!"); clearCart(); navigate("/order-confirmation"); } catch { toast.error("Payment could not be started. Please try again."); } }; const updateShipping = (field: string, value: string) => { setShipping((prev) => ({ ...prev, [field]: value })); if (errors[field]) setErrors((prev) => { const n = { ...prev }; delete n[field]; return n; }); }; const updatePayment = (field: string, value: string) => { setPayment((prev) => ({ ...prev, [field]: value })); if (errors[field]) setErrors((prev) => { const n = { ...prev }; delete n[field]; return n; }); }; return (
{/* Step Indicator */}
{steps.map((s, i) => (
= s.num ? "text-stone-900" : "text-stone-400"}`} onClick={() => s.num < step && setStep(s.num)}>
s.num ? "bg-green-500/80 text-white" : step === s.num ? "bg-stone-900/80 text-white" : "bg-white/80 dark:bg-slate-900/80 text-stone-500" }`}> {step > s.num ? : s.num}
{s.label}
{i < steps.length - 1 && (
s.num ? "bg-green-500" : "bg-stone-200"}`} /> )}
))}
{/* Main Form */}
{/* Step 1: Shipping */} {step === 1 && (

Shipping Information

{ e.preventDefault(); if (validateShipping()) setStep(2); }}>
updateShipping("firstName", e.target.value)} placeholder="John" className={`${errors.firstName ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.firstName && shipping.firstName.trim() && }
{errors.firstName &&

{errors.firstName}

}
updateShipping("lastName", e.target.value)} placeholder="Doe" className={`${errors.lastName ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.lastName && shipping.lastName.trim() && }
{errors.lastName &&

{errors.lastName}

}
updateShipping("email", e.target.value)} placeholder="john@example.com" className={`${errors.email ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.email && shipping.email?.includes("@") && }
{errors.email &&

{errors.email}

}
updateShipping("address", e.target.value)} placeholder="123 Main Street" className={`${errors.address ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.address && shipping.address.trim() && }
{errors.address &&

{errors.address}

}
updateShipping("city", e.target.value)} placeholder="New York" className={`${errors.city ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.city && shipping.city.trim() && }
{errors.city &&

{errors.city}

}
updateShipping("state", e.target.value)} placeholder="NY" />
updateShipping("zip", e.target.value)} placeholder="10001" className={`${errors.zip ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.zip && shipping.zip.trim() && }
{errors.zip &&

{errors.zip}

}
)} {/* Step 2: Payment */} {step === 2 && (

Payment Details

{ e.preventDefault(); if (validatePayment()) setStep(3); }}>
updatePayment("cardholder", e.target.value)} placeholder="John Doe" />
updatePayment("cardNumber", e.target.value)} placeholder="4242 4242 4242 4242" className={`${errors.cardNumber ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.cardNumber && payment.cardNumber.replace(/\s/g, "").length >= 16 && }
{errors.cardNumber &&

{errors.cardNumber}

}
updatePayment("expiry", e.target.value)} placeholder="MM/YY" className={`${errors.expiry ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.expiry && payment.expiry.trim() && }
{errors.expiry &&

{errors.expiry}

}
updatePayment("cvv", e.target.value)} placeholder="123" className={`${errors.cvv ? "border-red-500 focus-visible:ring-red-500" : ""}`} /> {!errors.cvv && payment.cvv.length >= 3 && }
{errors.cvv &&

{errors.cvv}

}
Your payment information is encrypted and secure.
)} {/* Step 3: Review */} {step === 3 && (

Review Your Order

{/* Items */}
{items.map((item) => (

{item.name}

Qty: {item.quantity} | {item.size} | {item.color}

${(item.price * item.quantity).toFixed(2)}
))}
{/* Shipping Address */}

Shipping Address

{shipping.firstName} {shipping.lastName}
{shipping.address}
{shipping.city}, {shipping.state} {shipping.zip}

{/* Payment */}

Payment Method

Card ending in {payment.cardNumber.slice(-4) || "****"}
)}
{/* Right Sidebar:Order Summary */}

Order Summary

{items.map((item) => (
{item.name} x{item.quantity} ${(item.price * item.quantity).toFixed(2)}
))}
Subtotal ${total.toFixed(2)}
Shipping {shippingCost === 0 ? "Free" : `$${shippingCost.toFixed(2)}`}
Tax ${tax.toFixed(2)}
Total ${grandTotal.toFixed(2)}
); }