Checkout.jsx 5.12 KB
import React, { useState } from 'react'
import { useCart } from '../context/CartContext'
import { useAuth } from '../context/AuthContext'
import { orderService } from '../services/api/orderService'
import CheckoutSteps from '../components/checkout/CheckoutSteps'
import ShippingForm from '../components/checkout/ShippingForm'
import PaymentForm from '../components/checkout/PaymentForm'
import OrderReview from '../components/checkout/OrderReview'
import LoadingSpinner from '../components/common/LoadingSpinner'
import toast from 'react-hot-toast'

const Checkout = () => {
  const [currentStep, setCurrentStep] = useState(1)
  const [loading, setLoading] = useState(false)
  const [orderData, setOrderData] = useState({
    shipping: {},
    payment: {}
  })

  const { cartItems, getCartTotal, clearCart } = useCart()
  const { user } = useAuth()

  const handleShippingSubmit = (shippingData) => {
    setOrderData({
      ...orderData,
      shipping: shippingData
    })
    setCurrentStep(2)
  }

  const handlePaymentSubmit = (paymentData) => {
    setOrderData({
      ...orderData,
      payment: paymentData
    })
    setCurrentStep(3)
  }

  const handleBack = () => {
    setCurrentStep(currentStep - 1)
  }

  const handlePlaceOrder = async () => {
    setLoading(true)
    try {
      const order = {
        items: cartItems,
        shippingAddress: orderData.shipping,
        paymentMethod: {
          type: 'card',
          ...orderData.payment
        },
        total: getCartTotal() * 1.1, // Including tax
        tax: getCartTotal() * 0.1
      }

      const result = await orderService.createOrder(order)
      clearCart()
      toast.success('Order placed successfully!')
      
      // Redirect to order confirmation
      window.location.href = `/orders/${result.order._id}`
    } catch (error) {
      toast.error('Failed to place order. Please try again.')
      console.error('Order error:', error)
    } finally {
      setLoading(false)
    }
  }

  if (cartItems.length === 0) {
    return (
      <div className="checkout-page">
        <div className="container">
          <div className="empty-cart">
            <h1>Your cart is empty</h1>
            <p>Add some products to your cart to checkout</p>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="checkout-page">
      <div className="container">
        <div className="checkout-header">
          <h1>Checkout</h1>
          <CheckoutSteps currentStep={currentStep} />
        </div>

        <div className="checkout-content">
          <div className="checkout-main">
            {currentStep === 1 && (
              <ShippingForm 
                onNext={handleShippingSubmit}
                initialData={orderData.shipping}
              />
            )}
            
            {currentStep === 2 && (
              <PaymentForm 
                onNext={handlePaymentSubmit}
                onBack={handleBack}
                initialData={orderData.payment}
              />
            )}
            
            {currentStep === 3 && (
              <OrderReview 
                orderData={orderData}
                cartItems={cartItems}
                onPlaceOrder={handlePlaceOrder}
                loading={loading}
                onBack={handleBack}
              />
            )}
          </div>

          <div className="checkout-sidebar">
            <div className="order-summary">
              <h3>Order Summary</h3>
              
              <div className="order-items">
                {cartItems.map(item => (
                  <div key={item.product._id} className="order-item">
                    <div className="item-image">
                      <img 
                        src={item.product.image} 
                        alt={item.product.name}
                        onError={(e) => {
                          e.target.src = '/placeholder-image.jpg'
                        }}
                      />
                    </div>
                    <div className="item-details">
                      <h4>{item.product.name}</h4>
                      <p>Qty: {item.quantity}</p>
                    </div>
                    <div className="item-price">
                      ${(item.price * item.quantity).toFixed(2)}
                    </div>
                  </div>
                ))}
              </div>

              <div className="order-totals">
                <div className="total-row">
                  <span>Subtotal:</span>
                  <span>${getCartTotal().toFixed(2)}</span>
                </div>
                <div className="total-row">
                  <span>Shipping:</span>
                  <span>Free</span>
                </div>
                <div className="total-row">
                  <span>Tax:</span>
                  <span>${(getCartTotal() * 0.1).toFixed(2)}</span>
                </div>
                <div className="total-row grand-total">
                  <span>Total:</span>
                  <span>${(getCartTotal() * 1.1).toFixed(2)}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

export default Checkout