import React, { useState } from 'react';
import {
Box,
Typography,
Paper,
Grid,
Stepper,
Step,
StepLabel,
Button,
Divider,
TextField,
FormControlLabel,
Checkbox,
CircularProgress,
List,
ListItem,
ListItemText,
Alert
} from '@mui/material';
import { useNavigate, Link as RouterLink } from 'react-router-dom';
import { useAuth, useCart } from '../hooks/reduxHooks';
import { useCheckout } from '../hooks/apiHooks';
// Checkout steps
const steps = ['Shipping Address', 'Review Order', 'Payment', 'Confirmation'];
const CheckoutPage = () => {
const navigate = useNavigate();
const { user } = useAuth();
const { items, total, itemCount } = useCart();
const checkout = useCheckout();
// State for checkout steps
const [activeStep, setActiveStep] = useState(0);
// State for form data
const [formData, setFormData] = useState({
firstName: user?.first_name || '',
lastName: user?.last_name || '',
email: user?.email || '',
address: '',
city: '',
state: '',
zipCode: '',
country: '',
saveAddress: false,
});
// Handle form changes
const handleChange = (e) => {
const { name, value, checked } = e.target;
setFormData({
...formData,
[name]: name === 'saveAddress' ? checked : value,
});
};
// Handle next step
const handleNext = () => {
if (activeStep === steps.length - 1) {
// Complete checkout - placeholder
return;
}
// If on shipping address step, validate form
if (activeStep === 0) {
if (!validateShippingForm()) {
return;
}
}
// If on review step, process checkout
if (activeStep === 1) {
handlePlaceOrder();
return;
}
setActiveStep((prevStep) => prevStep + 1);
};
// Handle back step
const handleBack = () => {
setActiveStep((prevStep) => prevStep - 1);
};
// Validate shipping form
const validateShippingForm = () => {
const requiredFields = ['firstName', 'lastName', 'email', 'address', 'city', 'state', 'zipCode', 'country'];
for (const field of requiredFields) {
if (!formData[field]) {
// In a real app, you'd set specific errors for each field
alert(`Please fill in all required fields`);
return false;
}
}
// Basic email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.email)) {
alert('Please enter a valid email address');
return false;
}
return true;
};
// Handle place order
const handlePlaceOrder = () => {
if (!user || !items || items.length === 0) {
return;
}
// Format shipping address for API
const shippingAddress = `${formData.firstName} ${formData.lastName}
${formData.address}
${formData.city}, ${formData.state} ${formData.zipCode}
${formData.country}
${formData.email}`;
checkout.mutate({
userId: user,
shippingAddress
}, {
onSuccess: () => {
// Move to confirmation step
setActiveStep(3);
}
});
};
// If no items in cart, redirect to cart page
if (!items || items.length === 0) {
return (
Your cart is empty
You need to add items to your cart before checkout.
);
}
// Render different step content based on active step
const getStepContent = (step) => {
switch (step) {
case 0:
return (
}
label="Save this address for future orders"
/>
);
case 1:
return (
{/* Order summary */}
Order Summary
{items.map((item) => (
${(parseFloat(item.price) * item.quantity).toFixed(2)}
))}
Free
${total.toFixed(2)}
{/* Shipping address */}
Shipping Address
{formData.firstName} {formData.lastName}
{formData.address}
{formData.city}, {formData.state} {formData.zipCode}
{formData.country}
{formData.email}
);
case 2:
// Placeholder for payment (in a real app, this would have a payment form)
return (
This is a demo application. No actual payment will be processed.
Payment Method
For this demo, we'll simulate a successful payment.
Total to pay: ${total.toFixed(2)}
);
case 3:
return (
Your order has been placed successfully!
Thank you for your order
Your order number is: #{Math.floor(100000 + Math.random() * 900000)}
We will send you a confirmation email with your order details.
);
default:
return Unknown step;
}
};
return (
Checkout
{steps.map((label) => (
{label}
))}
{getStepContent(activeStep)}
{activeStep !== 0 && activeStep !== 3 && (
)}
{activeStep !== 3 ? (
) : (
)}
);
};
export default CheckoutPage;