diff --git a/backend/src/middleware/upload.js b/backend/src/middleware/upload.js index e2b5087..679f1a2 100644 --- a/backend/src/middleware/upload.js +++ b/backend/src/middleware/upload.js @@ -52,7 +52,7 @@ const upload = multer({ storage, fileFilter, limits: { - fileSize: 5 * 1024 * 1024 // 5MB limit + fileSize: 10 * 1024 * 1024 // 10MB } }); diff --git a/backend/src/routes/auth.js b/backend/src/routes/auth.js index 9246c27..e6eb385 100644 --- a/backend/src/routes/auth.js +++ b/backend/src/routes/auth.js @@ -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)}`; diff --git a/backend/src/routes/cart.js b/backend/src/routes/cart.js index 6e5f028..1cb25eb 100644 --- a/backend/src/routes/cart.js +++ b/backend/src/routes/cart.js @@ -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 diff --git a/frontend/src/context/StripeContext.jsx b/frontend/src/context/StripeContext.jsx index 0ecbd7a..b0999d2 100644 --- a/frontend/src/context/StripeContext.jsx +++ b/frontend/src/context/StripeContext.jsx @@ -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 ( diff --git a/frontend/src/pages/Admin/DashboardPage.jsx b/frontend/src/pages/Admin/DashboardPage.jsx index 8cbac7c..5a51b4c 100644 --- a/frontend/src/pages/Admin/DashboardPage.jsx +++ b/frontend/src/pages/Admin/DashboardPage.jsx @@ -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 })); } diff --git a/frontend/src/pages/CheckoutPage.jsx b/frontend/src/pages/CheckoutPage.jsx index c5c68ed..4d6ead5 100644 --- a/frontend/src/pages/CheckoutPage.jsx +++ b/frontend/src/pages/CheckoutPage.jsx @@ -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 ( + + + + ); + } + // If no items in cart, redirect to cart page - if (!items || items.length === 0) { + if (!cart || !cart.items || cart.items.length === 0) { return ( @@ -489,7 +497,7 @@ const CheckoutPage = () => { - {items.map((item) => ( + {cart.items.map((item) => ( { - ${total.toFixed(2)} + ${cart.subtotal.toFixed(2)} @@ -519,7 +527,7 @@ const CheckoutPage = () => { - ${(total + shippingCost).toFixed(2)} + ${(cart.subtotal + shippingCost).toFixed(2)}