import React, { useState } from 'react'; import { X, Lock, CheckCircle2, CreditCard, Shield, Truck, Sparkles, ArrowLeft, ChevronRight, Check, Download } from 'lucide-react'; import { CartItem, Address, Order } from '../types'; import { downloadOrderInvoice } from '../utils/invoiceGenerator'; interface CheckoutModalProps { isOpen: boolean; onClose: () => void; items: CartItem[]; savedAddresses: Address[]; onOrderPlaced: (order: Order) => void; onOpenOrderInAccount: (orderId: string) => void; initialPaymentMethod?: 'Apple Pay' | 'Credit Card'; } export const CheckoutModal: React.FC = ({ isOpen, onClose, items, savedAddresses, onOrderPlaced, onOpenOrderInAccount, initialPaymentMethod = 'Credit Card', }) => { if (!isOpen) return null; // Selected saved address or custom input const defaultAddr = savedAddresses.find((a) => a.isDefault) || savedAddresses[0]; const [selectedSavedAddrId, setSelectedSavedAddrId] = useState(defaultAddr ? defaultAddr.id : 'custom'); const [addressForm, setAddressForm] = useState
( defaultAddr || { id: 'custom-addr', label: 'New Address', fullName: 'Eleanor Vance', street: '740 Park Avenue', apartment: 'Apt 14B', city: 'New York', state: 'NY', postalCode: '10021', country: 'United States', phone: '+1 (212) 555-0198', isDefault: false, } ); const [email, setEmail] = useState('eleanor.vance@vancemedia.com'); const [phone, setPhone] = useState('+1 (212) 555-0198'); const [shippingMethod, setShippingMethod] = useState<'standard' | 'express'>('standard'); const [paymentMethod, setPaymentMethod] = useState<'Apple Pay' | 'Credit Card'>(initialPaymentMethod); // Credit card state const [cardNumber, setCardNumber] = useState('4242 •••• •••• 4092'); const [cardExpiry, setCardExpiry] = useState('08/28'); const [cardCvc, setCardCvc] = useState('883'); const [cardName, setCardName] = useState('Eleanor Vance'); const [saveCard, setSaveCard] = useState(true); // Promo code state const [promoCode, setPromoCode] = useState(''); const [appliedPromo, setAppliedPromo] = useState<{ code: string; discountPercent?: number; fixedDiscount?: number } | null>({ code: 'WARDROBE15', discountPercent: 15, }); const [promoError, setPromoError] = useState(''); // Processing & Confirmation const [isSubmitting, setIsSubmitting] = useState(false); const [applePaySheetActive, setApplePaySheetActive] = useState(false); const [applePayBiometricState, setApplePayBiometricState] = useState<'scanning' | 'success' | 'idle'>('idle'); const [completedOrder, setCompletedOrder] = useState(null); // Price calculations const subtotal = items.reduce((acc, item) => acc + item.price * item.quantity, 0); const shippingCost = shippingMethod === 'express' ? 25 : 0; let discount = 0; if (appliedPromo) { if (appliedPromo.discountPercent) { discount = Math.round((subtotal * appliedPromo.discountPercent) / 100); } else if (appliedPromo.fixedDiscount) { discount = appliedPromo.fixedDiscount; } } const taxableAmount = Math.max(0, subtotal - discount); const tax = Math.round(taxableAmount * 0.08875); // NY Tax ~8.875% const finalTotal = taxableAmount + shippingCost + tax; const handleApplyPromo = () => { setPromoError(''); const code = promoCode.trim().toUpperCase(); if (code === 'WARDROBE15' || code === 'VIP15') { setAppliedPromo({ code, discountPercent: 15 }); setPromoCode(''); } else if (code === 'ATELIER') { setAppliedPromo({ code, fixedDiscount: 100 }); setPromoCode(''); } else { setPromoError('Voucher code invalid or expired. Try "WARDROBE15"'); } }; const handleSelectSavedAddress = (addr: Address) => { setSelectedSavedAddrId(addr.id); setAddressForm(addr); }; const executeOrderPlacement = (method: 'Apple Pay' | 'Credit Card') => { setIsSubmitting(true); setTimeout(() => { const newOrder: Order = { id: `TW-${Math.floor(10000 + Math.random() * 90000)}`, date: new Date().toISOString().split('T')[0], status: 'Preparing at Atelier', items: items.map((it) => ({ productId: it.productId, productName: it.product.name, image: it.selectedColor.image || it.product.images[0], colorName: it.selectedColor.name, size: it.selectedSize, quantity: it.quantity, price: it.price, })), subtotal, shippingMethod: shippingMethod === 'express' ? 'Priority Evening White-Glove Courier' : 'Complimentary White-Glove Delivery', shippingCost, discount, tax, total: finalTotal, shippingAddress: addressForm, paymentMethod: method, cardLastFour: method === 'Credit Card' ? cardNumber.slice(-4).replace(/\D/g, '') || '4092' : undefined, trackingNumber: `TW-COURIER-${Math.floor(1000000 + Math.random() * 9000000)}`, estimatedDelivery: '3 business days', }; setIsSubmitting(false); setCompletedOrder(newOrder); onOrderPlaced(newOrder); }, 1400); }; const triggerApplePayFlow = () => { setApplePaySheetActive(true); setApplePayBiometricState('scanning'); setTimeout(() => { setApplePayBiometricState('success'); setTimeout(() => { setApplePaySheetActive(false); executeOrderPlacement('Apple Pay'); }, 900); }, 1600); }; // Card formatting const handleCardNumberChange = (e: React.ChangeEvent) => { let val = e.target.value.replace(/\D/g, '').substring(0, 16); let formatted = val.match(/.{1,4}/g)?.join(' ') || val; setCardNumber(formatted); }; return (
{/* Top Luxury Checkout Navigation Bar */}
256-Bit SSL Encrypted Checkout
The Wardrobe
{/* ORDER CONFIRMATION VIEW */} {completedOrder ? (
Order Confirmed • Atelier Notified

Thank You, {addressForm.fullName}

Your garments are being prepared at our master atelier in Biella and Paris. An executive dispatch confirmation has been dispatched to {email}.

{/* Receipt Summary Card */}
Order Reference {completedOrder.id}
Payment Method {completedOrder.paymentMethod}
Delivery Address

{addressForm.fullName} • {addressForm.street}, {addressForm.apartment && `${addressForm.apartment}, `}{addressForm.city}, {addressForm.state} {addressForm.postalCode}

Purchased Ensemble {completedOrder.items.map((it, idx) => (
{it.quantity}x {it.productName} ({it.size}, {it.colorName}) ${(it.price * it.quantity).toLocaleString()}
))}
Total Charged ${completedOrder.total.toLocaleString()}
) : ( /* ONE-PAGE CHECKOUT FORM */
{/* Left Column: Form Details (7 cols) */}
{/* Express Apple Pay Banner */}
Express Luxury Checkout
Or Complete Below
{/* Step 1: Contact Information */}

1 Contact Information

Logged in as Gold VIP Client
setEmail(e.target.value)} className="w-full bg-white border border-neutral-300 px-3.5 py-2.5 text-xs text-black focus:outline-none focus:border-[#B88E4B]" />
setPhone(e.target.value)} className="w-full bg-white border border-neutral-300 px-3.5 py-2.5 text-xs text-black focus:outline-none focus:border-[#B88E4B]" />
{/* Step 2: Shipping Destination & Saved Addresses */}

2 Shipping Destination

Saved Addresses Available
{/* Saved Address Quick Select */} {savedAddresses.length > 0 && (
{savedAddresses.map((addr) => (
handleSelectSavedAddress(addr)} className={`p-3.5 border cursor-pointer transition-all ${ selectedSavedAddrId === addr.id ? 'bg-[#FAF7EF] border-[#B88E4B] ring-1 ring-[#B88E4B]' : 'bg-white border-neutral-200 hover:border-neutral-400' }`} >
{addr.label} {addr.isDefault && ( Default )}

{addr.fullName}, {addr.street}, {addr.city}, {addr.state} {addr.postalCode}

))}
)} {/* Form fields */}
setAddressForm({ ...addressForm, fullName: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
setAddressForm({ ...addressForm, street: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
setAddressForm({ ...addressForm, apartment: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
setAddressForm({ ...addressForm, city: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
setAddressForm({ ...addressForm, state: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
setAddressForm({ ...addressForm, postalCode: e.target.value })} className="w-full border border-neutral-300 px-3 py-2 text-xs focus:outline-none focus:border-[#B88E4B]" />
{/* Step 3: Courier Selection */}

3 Delivery Method

{/* Step 4: Payment Method */}

4 Payment Method

{/* Method selector tabs */}
{/* Credit card fields */} {paymentMethod === 'Credit Card' && (
Visa • Mastercard • Amex
setCardExpiry(e.target.value)} placeholder="MM/YY" className="w-full border border-neutral-300 px-3 py-2 text-xs text-black focus:outline-none focus:border-[#B88E4B]" />
setCardCvc(e.target.value)} maxLength={4} placeholder="•••" className="w-full border border-neutral-300 px-3 py-2 text-xs text-black focus:outline-none focus:border-[#B88E4B]" />
setCardName(e.target.value)} className="w-full border border-neutral-300 px-3 py-2 text-xs text-black focus:outline-none focus:border-[#B88E4B]" />
)} {/* Apple pay info */} {paymentMethod === 'Apple Pay' && (

One-Touch Biometric Authentication

Clicking 'Complete Purchase' will initiate the native Apple Pay authorization prompt with Face ID / Touch ID verification.

)}
{/* Right Column: Sticky Order Review & Confirmation Action (5 cols) */}

Order Summary ({items.length} {items.length === 1 ? 'Piece' : 'Pieces'})

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

{it.product.name}

{it.selectedColor.name} • Size {it.selectedSize} • Qty: {it.quantity}

${(it.price * it.quantity).toLocaleString()}

))}
{/* Promo Code Input */}
setPromoCode(e.target.value)} placeholder="VIP Voucher (e.g. WARDROBE15)" className="flex-1 border border-neutral-300 px-3 py-2 text-xs uppercase focus:outline-none focus:border-[#B88E4B]" />
{appliedPromo && (
Voucher '{appliedPromo.code}' Active
)} {promoError &&

{promoError}

}
{/* Cost Breakdown */}
Subtotal ${subtotal.toLocaleString()}
{discount > 0 && (
VIP Privilege Discount -${discount.toLocaleString()}
)}
White-Glove Courier {shippingCost === 0 ? 'Complimentary' : `$${shippingCost}`}
Sales Tax (NY 8.875%) ${tax.toLocaleString()}
Total Due ${finalTotal.toLocaleString()}
{/* Action Button */}
{paymentMethod === 'Apple Pay' ? ( ) : ( )}
30-Day Home Trial Free Returns Bespoke Hemming
)} {/* Realistic Apple Pay Biometric Sheet Modal Simulation */} {applePaySheetActive && (
Pay The Wardrobe Boutique
{/* Biometric Scanning Visual */}
{applePayBiometricState === 'scanning' ? (
) : (
)}

{applePayBiometricState === 'scanning' ? 'Verifying with Face ID...' : 'Payment Authorized'}

Apple Card •••• 4092

${finalTotal.toLocaleString()}

Shipped to {addressForm.street}, {addressForm.city}

)}
); };

Comments

Popular posts from this blog