fixed cart desync

This commit is contained in:
2ManyProjects 2025-04-28 15:38:46 -05:00
parent 202e99b12f
commit c913b09edf
6 changed files with 54 additions and 25 deletions

View file

@ -52,7 +52,7 @@ const upload = multer({
storage,
fileFilter,
limits: {
fileSize: 5 * 1024 * 1024 // 5MB limit
fileSize: 10 * 1024 * 1024 // 10MB
}
});

View file

@ -15,7 +15,6 @@ const createTransporter = () => {
});
};
// Mock email transporter for development
const transporter = createTransporter();
module.exports = (pool, query) => {
@ -94,7 +93,6 @@ module.exports = (pool, query) => {
[authId, user.id]
);
// Send email with code (mock in development)
const loginLink = `${config.site.protocol}://${config.site.domain}/verify?code=${authCode}&email=${encodeURIComponent(email)}`;

View file

@ -513,7 +513,6 @@ module.exports = (pool, query, authMiddleware) => {
? shippingService.parseAddressString(shippingAddress)
: shippingAddress;
console.log("Fetching rates for parsed address:", parsedAddress);
const shippingResponse = await shippingService.getShippingRates(
null, // Use default from config

View file

@ -3,6 +3,7 @@ import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import config from '../config';
import apiClient from '@services/api';
import { useAuth } from '@hooks/reduxHooks';
// Create the context
const StripeContext = createContext();
@ -12,13 +13,19 @@ export const StripeProvider = ({ children }) => {
const [clientSecret, setClientSecret] = useState('');
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const { isAuthenticated } = useAuth();
// Load or reload Stripe configuration when authentication state changes
useEffect(() => {
// Reset state when auth changes
setIsLoading(true);
setError(null);
// Try to load Stripe public key from environment
let publicKey = import.meta.env.VITE_STRIPE_PUBLIC_KEY;
// If not found, fetch from API
if (!publicKey) {
if (isAuthenticated) {
// Fetch Stripe public key from backend
apiClient.get('/payment/config')
.then(response => {
@ -34,10 +41,10 @@ export const StripeProvider = ({ children }) => {
setError('Failed to load payment configuration');
setIsLoading(false);
});
} else {
} else if(publicKey){
loadStripeInstance(publicKey);
}
}, []);
}, [isAuthenticated]); // Add isAuthenticated as a dependency to reload on auth changes
const loadStripeInstance = (publicKey) => {
try {
@ -102,7 +109,27 @@ export const StripeProvider = ({ children }) => {
error,
createCheckoutSession,
checkSessionStatus,
completeOrder
completeOrder,
reloadConfig: () => {
setIsLoading(true);
setError(null);
if (isAuthenticated){
apiClient.get('/payment/config')
.then(response => {
if (response.data.stripePublicKey) {
loadStripeInstance(response.data.stripePublicKey);
} else {
setError('Stripe public key not found');
setIsLoading(false);
}
})
.catch(err => {
console.error('Error fetching Stripe config:', err);
setError('Failed to load payment configuration');
setIsLoading(false);
});
}
}
};
return (

View file

@ -28,7 +28,6 @@ import apiClient from '../../services/api';
import { useAdminCategories } from '../../hooks/categoryAdminHooks';
const AdminDashboardPage = () => {
// Mock data - would be replaced with real API calls
const [stats, setStats] = useState({
totalProducts: 0,
totalUsers: 0,
@ -53,7 +52,6 @@ const AdminDashboardPage = () => {
// Fetch categories
const { data: categories, isLoading: categoriesLoading } = useAdminCategories();
// Mock recent orders - would be replaced with real API data
const recentOrders = [
{ id: '4532', customer: 'John Doe', date: '2023-04-22', total: 49.99, status: 'Delivered' },
{ id: '4531', customer: 'Jane Smith', date: '2023-04-21', total: 89.95, status: 'Processing' },
@ -67,10 +65,9 @@ const AdminDashboardPage = () => {
setStats(prev => ({
...prev,
totalProducts: products.length,
// Other stats would be updated from their respective API calls
totalUsers: 15, // Mock data
totalOrders: 42, // Mock data
revenue: 2459.99 // Mock data
totalUsers: 15,
totalOrders: 42,
revenue: 2459.99
}));
}

View file

@ -23,8 +23,8 @@ import {
FormLabel
} from '@mui/material';
import { useNavigate, Link as RouterLink } from 'react-router-dom';
import { useAuth, useCart } from '../hooks/reduxHooks';
import { useCheckout } from '../hooks/apiHooks';
import { useAuth } from '../hooks/reduxHooks';
import { useCheckout, useGetCart } from '../hooks/apiHooks';
import { useStripe, StripeElementsProvider } from '../context/StripeContext';
import apiClient from '../services/api';
@ -34,7 +34,7 @@ const steps = ['Shipping Address', 'Shipping Method', 'Review Order', 'Payment',
const CheckoutPage = () => {
const navigate = useNavigate();
const { user, userData } = useAuth();
const { items, total, itemCount } = useCart();
const { data: cart, isLoading: cartLoading } = useGetCart(user);
const checkout = useCheckout();
const { createCheckoutSession, isLoading: isStripeLoading } = useStripe();
@ -54,8 +54,8 @@ const CheckoutPage = () => {
// State for form data
const [formData, setFormData] = useState({
firstName: userData?.first_name || '',
lastName: userData?.last_name || '',
firstName: userData?.firstName || '',
lastName: userData?.lastName || '',
email: userData?.email || '',
address: '',
city: '',
@ -125,7 +125,6 @@ const CheckoutPage = () => {
for (const field of requiredFields) {
if (!formData[field]) {
// In a real app, you'd set specific errors for each field
setError(`Please fill in all required fields`);
return false;
}
@ -210,7 +209,7 @@ const CheckoutPage = () => {
// Handle place order
const handlePlaceOrder = async () => {
if (!user || !items || items.length === 0) {
if (!user || !cart || !cart.items || cart.items.length === 0) {
return;
}
@ -280,8 +279,17 @@ const CheckoutPage = () => {
}
}, [checkoutUrl]);
// Loading state
if (cartLoading) {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', my: 8 }}>
<CircularProgress />
</Box>
);
}
// If no items in cart, redirect to cart page
if (!items || items.length === 0) {
if (!cart || !cart.items || cart.items.length === 0) {
return (
<Box sx={{ textAlign: 'center', py: 6 }}>
<Typography variant="h5" gutterBottom>
@ -489,7 +497,7 @@ const CheckoutPage = () => {
</Typography>
<List disablePadding>
{items.map((item) => (
{cart.items.map((item) => (
<ListItem key={item.product_id} sx={{ py: 1, px: 0 }}>
<ListItemText
primary={item.name}
@ -503,7 +511,7 @@ const CheckoutPage = () => {
<ListItem sx={{ py: 1, px: 0 }}>
<ListItemText primary="Subtotal" />
<Typography variant="body2">${total.toFixed(2)}</Typography>
<Typography variant="body2">${cart.subtotal.toFixed(2)}</Typography>
</ListItem>
<ListItem sx={{ py: 1, px: 0 }}>
@ -519,7 +527,7 @@ const CheckoutPage = () => {
<ListItem sx={{ py: 1, px: 0 }}>
<ListItemText primary="Total" />
<Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
${(total + shippingCost).toFixed(2)}
${(cart.subtotal + shippingCost).toFixed(2)}
</Typography>
</ListItem>
</List>