Skip to content

Commit

Permalink
cartContext con los productos y su estado, checkout empezado
Browse files Browse the repository at this point in the history
  • Loading branch information
Adolfopgv committed May 29, 2024
1 parent e0f6430 commit b24061d
Show file tree
Hide file tree
Showing 10 changed files with 420 additions and 117 deletions.
35 changes: 28 additions & 7 deletions backend/controllers/cartController.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ const addToCart = async (req, res) => {
const cart = await Cart.findOne({ userId });

if (!cart) {
const newCart = new Cart({
await Cart.create({
userId,
products: [{ product: productId, quantity: 1 }],
});
await newCart.save();
return res.status(200).json({ message: "Producto añadido al carrito" });
}

const productIndex = cart.products.findIndex(
(p) => p.product.toString() === productId
const productInCart = cart.products.find(
(item) => item.product.toString() === productId
);

if (productIndex !== -1) {
cart.products[productIndex].quantity += 1;
if (productInCart) {
productInCart.quantity += 1;
} else {
cart.products.push({ product: productId, quantity: 1 });
}
Expand All @@ -40,7 +39,29 @@ const addToCart = async (req, res) => {

const removeFromCart = async (req, res) => {
try {
} catch (error) {}
const userId = req.params.userid;
const productId = req.params.product;

const cart = await Cart.findOne({ userId });

const productInCart = cart.products.find(
(item) => item.product.toString() === productId
);

if (productInCart && productInCart.quantity > 1) {
productInCart.quantity -= 1;
} else if (productInCart.quantity <= 1) {
productInCart.deleteOne();
} else {
return res.json({ error: "No se ha podido eliminar el producto" });
}

await cart.save();

res.status(200).json({ message: "Producto eliminado" });
} catch (error) {
res.status(500).json({ error: "Error del servidor" });
}
};

const getCartProducts = async (req, res) => {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EmailVerification,
AdminDashboard,
AdminProducts,
Checkout,
} from "./Routes";
import axios from "axios";
import { Toaster } from "react-hot-toast";
Expand Down Expand Up @@ -60,6 +61,7 @@ export default function App() {
path="/admin-dashboard/products"
element={<AdminProducts />}
/>
<Route path="/checkout" element={<Checkout />} />
<Route path="/*" element={<Error />} />
</Routes>
<Footer />
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/Routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import EmailVerification from "./pages/error/EmailVerification.jsx";
import AdminDashboard from "./pages/admin/AdminDashboard.jsx";
import AdminProducts from "./pages/admin/AdminProducts.jsx";
import Product from "./pages/Product.jsx";
import Checkout from "./pages/Checkout.jsx";

export {
Login,
Expand All @@ -27,5 +28,6 @@ export {
Error,
EmailVerification,
AdminDashboard,
AdminProducts
AdminProducts,
Checkout
};
56 changes: 24 additions & 32 deletions frontend/src/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,29 @@ export default function Footer() {

const footer = (
<footer className="footer p-10 bg-base-200 text-base-content">
<aside>
<img className="w-24" src={laxart_logo} alt="Logo" />
<p>
Laxart Shop
<br />
Adults are only kids grown up, anyway.
</p>
</aside>
<nav>
<h6 className="footer-title">Empresa</h6>
<Link to="/about" className="link link-hover">
Sobre el proyecto
</Link>
<Link to="/contact" className="link link-hover">
Contacto
</Link>
</nav>
<nav>
<h6 className="footer-title">Legal</h6>
<a className="link link-hover">Terminos y condiciones</a>
</nav>
</footer>
)

return (
<>
{user && user.role !== 1 ? (
footer
) : (
footer
)}
</>
<aside>
<img className="w-24" src={laxart_logo} alt="Logo" />
<p>
Laxart Shop
<br />
Adults are only kids grown up, anyway.
</p>
</aside>
<nav>
<h6 className="footer-title">Empresa</h6>
<Link to="/about" className="link link-hover">
Sobre el proyecto
</Link>
<Link to="/contact" className="link link-hover">
Contacto
</Link>
</nav>
<nav>
<h6 className="footer-title">Legal</h6>
<a className="link link-hover">Terminos y condiciones</a>
</nav>
</footer>
);

return <>{user && user.role !== 1 ? footer : <div></div>}</>;
}
20 changes: 1 addition & 19 deletions frontend/src/components/NavbarLoggedIn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,6 @@ import ShoppingCartComponent from "./ShoppingCartComponent";
export default function NavbarLoggedIn({ genres }) {
const navigate = useNavigate();
const { user, setUser } = useContext(UserContext);
const { productAdded, setProductAdded } = useContext(CartContext);
const [cartProducts, setCartProducts] = useState([]);

useEffect(() => {
if (user) {
const fetchCartProducts = async () => {
try {
const response = await axios.get(`/get-cart-products/${user._id}`);
if (!response.data.error) {
setCartProducts(response.data);
}
} catch (error) {
console.error(error);
}
};
fetchCartProducts();
}
}, [user, productAdded]);

const logoutUser = async () => {
try {
Expand Down Expand Up @@ -136,7 +118,7 @@ export default function NavbarLoggedIn({ genres }) {
{/** Icono de busqueda (Queda mal en mobiles) */}

{/** Carrito de compra */}
{user.role !== 1 && <ShoppingCartComponent cartProducts={cartProducts} />}
{user.role !== 1 && <ShoppingCartComponent />}

{/**Avatar desplegable */}
<div className="mr-4 dropdown dropdown-end">
Expand Down
64 changes: 19 additions & 45 deletions frontend/src/components/ShoppingCartComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,28 @@
import { Link } from "react-router-dom";
import { memo, useState, useEffect } from "react";
import { memo, useState, useEffect, useContext } from "react";
import { UserContext } from "../context/userContext";
import { CartContext } from "../context/cartContext";
import axios from "axios";
import toast from "react-hot-toast";

const ShoppingCartComponent = ({ cartProducts }) => {
const [products, setProducts] = useState([]);
const [totalPrice, setTotalPrice] = useState(0);
const [quantity, setQuantity] = useState(0);
const ShoppingCartComponent = () => {
const { user } = useContext(UserContext);
const { setCartChanged, products, quantity, totalPrice } =
useContext(CartContext);

useEffect(() => {
console.log("Cart Products:", cartProducts);
const deleteCartProduct = async (productId) => {
try {
const response = await axios.delete(
`/remove-from-cart/${user._id}/${productId}`
);

if (!Array.isArray(cartProducts)) {
console.error("cartProducts is not an array:", cartProducts);
return;
}

const getProducts = async () => {
try {
const productDetails = await Promise.all(
cartProducts.map(async (cartProduct) => {
const response = await axios.get(
`/get-product/${cartProduct.product}`
);
return { ...response.data, quantity: cartProduct.quantity };
})
);

setProducts(productDetails);

const totalQuantity = productDetails.reduce(
(acc, product) => acc + product.quantity,
0
);
setQuantity(totalQuantity);

const total = productDetails.reduce(
(acc, curr) => acc + Number(curr.price) * curr.quantity,
0
);
setTotalPrice(total);
} catch (error) {
console.error(error);
if (!response.data.error) {
toast.success(response.data.message);
setCartChanged((val) => !val);
} else {
toast.error(response.data.error);
}
};

getProducts();
}, [cartProducts]);

const deleteCartProduct = (productId) => {
// Lógica para eliminar el producto del carrito
} catch (error) {}
};

return (
Expand Down
76 changes: 69 additions & 7 deletions frontend/src/context/cartContext.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,76 @@
import { createContext, useState } from "react";
import { createContext, useState, useEffect, useContext } from "react";
import { UserContext } from "./userContext";
import axios from "axios";

export const CartContext = createContext({
productAdded: false,
setProductAdded: () => {},
});
export const CartContext = createContext({});

export function CartContextProvider({ children }) {
const [productAdded, setProductAdded] = useState(false);
const [cartChanged, setCartChanged] = useState(false);
const [cartProducts, setCartProducts] = useState([]);
const { user } = useContext(UserContext);
const [products, setProducts] = useState([]);
const [totalPrice, setTotalPrice] = useState(0);
const [quantity, setQuantity] = useState(0);

useEffect(() => {
if (user) {
const fetchCartProducts = async () => {
try {
const response = await axios.get(`/get-cart-products/${user._id}`);
if (!response.data.error) {
setCartProducts(response.data);
}
} catch (error) {
console.error(error);
}
};
fetchCartProducts();
}
}, [user, cartChanged]);

useEffect(() => {
const getProducts = async () => {
try {
const productDetails = await Promise.all(
cartProducts.map(async (cartProduct) => {
const response = await axios.get(
`/get-product/${cartProduct.product}`
);
return { ...response.data, quantity: cartProduct.quantity };
})
);

setProducts(productDetails);

const totalQuantity = productDetails.reduce(
(acc, product) => acc + product.quantity,
0
);
setQuantity(totalQuantity);

const total = productDetails.reduce(
(acc, curr) => acc + Number(curr.price) * curr.quantity,
0
);
setTotalPrice(total);
} catch (error) {
console.error(error);
}
};

getProducts();
}, [cartProducts]);

return (
<CartContext.Provider value={{ productAdded, setProductAdded }}>
<CartContext.Provider
value={{
cartChanged,
setCartChanged,
products,
totalPrice,
quantity,
}}
>
{children}
</CartContext.Provider>
);
Expand Down
Loading

0 comments on commit b24061d

Please sign in to comment.