'use client'; import { useEffect, useState } from 'react'; import { api, formatPrice, type CartItem } from '@/lib/api'; import { useAuth } from '@/components/auth-provider'; import { useRouter } from 'next/navigation'; import { useToast } from '@/hooks/use-toast'; import { Store, MapPin, CreditCard, ChevronLeft, Check } from 'lucide-react'; import Link from 'next/link'; import { PageSkeleton } from '@/components/page-skeleton'; export default function CheckoutPage() { const { user, loading: authLoading } = useAuth(); const router = useRouter(); const { toast } = useToast(); const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [placing, setPlacing] = useState(false); const [profile, setProfile] = useState(null); const [fullName, setFullName] = useState(''); const [phone, setPhone] = useState(''); const [address, setAddress] = useState(''); const [city, setCity] = useState(''); const [state, setState] = useState(''); const [bankName, setBankName] = useState(''); const [notes, setNotes] = useState(''); useEffect(() => { if (!authLoading && !user) { router.push('/login?next=/checkout'); return; } if (user) { (async () => { const [cartResp, profileResp] = await Promise.all([ api.cart.get(), api.profile.get(), ]); if (cartResp.success) { setItems(cartResp.items || []); if ((cartResp.items || []).length === 0) { router.push('/cart'); return; } } if (profileResp.success && profileResp.profile) { setProfile(profileResp.profile); setFullName(profileResp.profile.full_name || ''); setPhone(profileResp.profile.phone || ''); setAddress(profileResp.profile.address || ''); } setLoading(false); })(); } }, [user, authLoading, router]); const subtotal = items.reduce((sum, i) => sum + (i.products?.price || 0) * i.quantity, 0); const shipping = subtotal > 50000 ? 0 : 1500; const total = subtotal + shipping; const placeOrder = async () => { if (!fullName || !phone || !address || !bankName) { toast({ title: 'Missing info', description: 'Please fill name, phone, address, and bank', variant: 'destructive' }); return; } setPlacing(true); // Save profile updates in parallel with order creation api.profile.update({ fullName, phone, address }).catch(() => {}); // Build items summary for the payment order const itemsSummary = items .map((i) => `${i.products?.name || 'Item'} x${i.quantity}`) .join(', '); // Create a payment_order via the payment edge function (PalmPay flow) const result = await api.payment.createOrder({ buyerName: fullName, buyerEmail: user?.email || '', buyerPhone: phone, buyerBankName: bankName || undefined, // used for name + bank + amount matching itemsSummary, itemCount: items.reduce((s, i) => s + i.quantity, 0), total, }); setPlacing(false); if (result.success && result.orderId) { toast({ title: 'Order placed!', description: 'Redirecting to payment...' }); router.push(`/payment?order=${result.orderId}`); } else { toast({ title: 'Error', description: result.error || 'Failed to place order', variant: 'destructive' }); } }; if (authLoading || loading) { return ( ); } const inputClass = "w-full bg-white/5 border border-white/10 rounded-md px-3 py-2.5 text-sm focus:bg-white/10 focus:border-white/10 outline-none"; const labelClass = "text-xs font-semibold text-slate-300"; return (
{/* Top bar */}

Checkout

{/* Shipping Address */}

Shipping Address

setFullName(e.target.value)} placeholder="John Doe" className={inputClass} />
setPhone(e.target.value)} placeholder="08012345678" className={inputClass} />
setState(e.target.value)} placeholder="Lagos" className={inputClass} />

Used to match your PalmPay transfer email — must match the bank you transfer from.