diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index e2b8608..5e0ad07 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -12,7 +12,7 @@ import AddProdutcAdmin from './pages/admin/AddProdcutAdmin'; import ManageProducts from './pages/admin/ManageProducts'; import ManageOrders from './pages/admin/ManageOrders'; import Profile from './pages/user/Profile'; -import OrderHistory from './pages/user/OrderHistory'; +import OrdersHistoryByUser from './pages/user/OrdersHistoryByUser' import PrivateRoute from './components/routes/PrivateRoute'; import jwt_decode from "jwt-decode"; import Swal from 'sweetalert2'; @@ -33,10 +33,15 @@ const App: FC = () => { if(user){ const exist = cartItems.find(x=> x.codigo === prod.codigo); if(exist){ - setCartItems(cartItems.map(x=> x.codigo === prod.codigo ? {...exist, cantidad : exist.cantidad +1} : x)) + exist.cantidad+=1 + setCartItems(cartItems.map(x=> x.codigo === prod.codigo ?{ ...x, exist } : x)) } else { - setCartItems([...cartItems,{...prod,cantidad:1}]) + prod.cantidad = 1; + cartItems.push(prod) + setCartItems([...cartItems]) } + console.log("CARRO ---> " + JSON.stringify(cartItems)) + localStorage.setItem('carrito',JSON.stringify(cartItems)) }else{ Swal.fire({ title: "Debes iniciar sesión", @@ -67,7 +72,7 @@ const App: FC = () => { }/> }/> } /> - } /> + } /> }/> }/> } /> diff --git a/webapp/src/api/ApiUsers.ts b/webapp/src/api/ApiUsers.ts index b8cf59c..e8f5d7a 100644 --- a/webapp/src/api/ApiUsers.ts +++ b/webapp/src/api/ApiUsers.ts @@ -81,7 +81,7 @@ export const foundEmail = async (email: String):Promise => { } export async function getUserById(id: string) { - const apiEndPoint= process.env.REACT_APP_API_URI || 'http://localhost:5000/' + const apiEndPoint= process.env.REACT_APP_API_URI || 'http://localhost:5000' let response = await fetch(apiEndPoint+'/user/findById/' + id); //The objects returned by the api are directly convertible to User objects return response.json() diff --git a/webapp/src/components/Products.tsx b/webapp/src/components/Products.tsx index c3bdaf2..5a84a55 100644 --- a/webapp/src/components/Products.tsx +++ b/webapp/src/components/Products.tsx @@ -9,7 +9,7 @@ import {v4 as uuidv4} from 'uuid'; type ProductsProps = { product: Product[] onAddCart:(prod:Product) => (void); - cartItems:Product[] + cartItems:Object[] homePage: boolean } diff --git a/webapp/src/components/navbar/NavBar.tsx b/webapp/src/components/navbar/NavBar.tsx index c771be4..cb19d5b 100644 --- a/webapp/src/components/navbar/NavBar.tsx +++ b/webapp/src/components/navbar/NavBar.tsx @@ -6,11 +6,8 @@ import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; import { Menu } from '@mui/material'; -import { MenuItem } from '@mui/material'; -import { AccountCircle } from '@mui/icons-material'; import Badge from '@mui/material/Badge'; import { Product } from '../../shared/shareddtypes'; -import Link from '@mui/material/Link'; import DeleteIcon from '@mui/icons-material/Delete'; import { Container } from '@mui/material'; import jwt_decode from 'jwt-decode'; @@ -23,26 +20,33 @@ type ProductsProps = { const NavBar=(cart:ProductsProps) =>{ const [anchorEl, setAnchorEl] = React.useState(null); - const [anchorElb, setAnchorElb] = React.useState(null); const open = Boolean(anchorEl); - const openB = Boolean(anchorElb); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; - const handleMenu = (event: React.MouseEvent) => { - setAnchorElb(event.currentTarget); - }; - const handleCloseMenu = () => { - setAnchorElb(null); - }; + var totalPrice = 0; var numOfProducts = 0 cart.cartItems.map(x => numOfProducts+= x.cantidad); cart.cartItems.map(x => totalPrice+= x.cantidad * x.precio); - console.log( cart.cartItems) + const carrt = localStorage.getItem("carrito"); + if(carrt !== null){ + for(let i =0; i < JSON.parse(carrt).length; i++){ + cart.cartItems[i] = { + nombre: JSON.parse(carrt)[i]['nombre'], + codigo: JSON.parse(carrt)[i]['codigo'], + descripcion: JSON.parse(carrt)[i]['descripcion'], + precio: JSON.parse(carrt)[i]['precio'], + cantidad: JSON.parse(carrt)[i]['cantidad'], + url: JSON.parse(carrt)[i]['url'], + stock: JSON.parse(carrt)[i]['stock'], + categoria: JSON.parse(carrt)[i]['categoria'], + } + } + } function mover(){ localStorage.setItem("carrito", JSON.stringify(cart.cartItems)); @@ -54,8 +58,10 @@ const NavBar=(cart:ProductsProps) =>{ if(index > -1){ if(cart.cartItems[index].cantidad > 1){ cart.cartItems[index].cantidad = cart.cartItems[index].cantidad -1 ; + localStorage.setItem("carrito",JSON.stringify(cart.cartItems)); } else{ cart.cartItems.splice(index); + localStorage.setItem("carrito",JSON.stringify(cart.cartItems)); } } } @@ -68,7 +74,7 @@ const NavBar=(cart:ProductsProps) =>{ const cerrarSesion = () => { Swal.fire({ title: '¿Quieres cerrar sesión?', - text: "Se perderan los productos que teine en el carrito", + text: "Se perderan los productos que tiene en el carrito", icon: 'warning', showCancelButton: true, confirmButtonColor: '#3085d6', @@ -103,7 +109,7 @@ const NavBar=(cart:ProductsProps) =>{ - + @@ -166,38 +172,6 @@ const NavBar=(cart:ProductsProps) =>{ )} - - - - - - Perfil - - - Historial de Pedidos - - diff --git a/webapp/src/components/navbar/NavBarAdmin.tsx b/webapp/src/components/navbar/NavBarAdmin.tsx index 82ce9d2..9bcf536 100644 --- a/webapp/src/components/navbar/NavBarAdmin.tsx +++ b/webapp/src/components/navbar/NavBarAdmin.tsx @@ -6,11 +6,8 @@ import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; import { Menu } from '@mui/material'; -import { MenuItem } from '@mui/material'; -import { AccountCircle } from '@mui/icons-material'; import Badge from '@mui/material/Badge'; import { Product } from '../../shared/shareddtypes'; -import Link from '@mui/material/Link'; import DeleteIcon from '@mui/icons-material/Delete'; import { Container } from '@mui/material'; import Swal from 'sweetalert2'; @@ -21,27 +18,19 @@ type ProductsProps = { const NavBarAdmin = (cart:ProductsProps) => { const [anchorEl, setAnchorEl] = React.useState(null); - const [anchorElb, setAnchorElb] = React.useState(null); const open = Boolean(anchorEl); - const openB = Boolean(anchorElb); const handleClick = (event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; - const handleMenu = (event: React.MouseEvent) => { - setAnchorElb(event.currentTarget); - }; - const handleCloseMenu = () => { - setAnchorElb(null); - }; var totalPrice = 0; var numOfProducts = 0 cart.cartItems.map(x => numOfProducts+= x.cantidad); cart.cartItems.map(x => totalPrice+= x.cantidad * x.precio); - const carrt = localStorage.getItem("cart"); + const carrt = localStorage.getItem("carrito"); if(carrt !== null){ for(let i =0; i < JSON.parse(carrt).length; i++){ cart.cartItems[i] = { @@ -62,8 +51,10 @@ const NavBarAdmin = (cart:ProductsProps) => { if(index > -1){ if(cart.cartItems[index].cantidad > 1){ cart.cartItems[index].cantidad = cart.cartItems[index].cantidad -1 ; + localStorage.setItem("carrito",JSON.stringify(cart.cartItems)); } else{ - cart.cartItems.splice(index); + cart.cartItems.splice(index,1); + localStorage.setItem("carrito",JSON.stringify(cart.cartItems)); } } } @@ -112,6 +103,7 @@ const NavBarAdmin = (cart:ProductsProps) => { DeDe + @@ -176,38 +168,6 @@ const NavBarAdmin = (cart:ProductsProps) => { )} - - - - - - Perfil - - - Historial de Ventas - - diff --git a/webapp/src/pages/Home.tsx b/webapp/src/pages/Home.tsx index 590fe49..42d3e7f 100644 --- a/webapp/src/pages/Home.tsx +++ b/webapp/src/pages/Home.tsx @@ -9,7 +9,7 @@ import Typography from '@mui/material/Typography'; type ProductsProps = { onAddCart:(prod:Product) => (void); - cartItems:Product[] + cartItems:Object[] } function cargarBanner(){ diff --git a/webapp/src/pages/Pago.tsx b/webapp/src/pages/Pago.tsx index 964e55a..5990e3c 100644 --- a/webapp/src/pages/Pago.tsx +++ b/webapp/src/pages/Pago.tsx @@ -88,7 +88,7 @@ const Pago: FC = () => { || tarjeta.length < 16 || tarjeta.length > 16 || cvv.length > 3 || cvv.length < 3){ Swal.fire({ title: "Creedenciales incorrectos", - text: "Los campos introducidos son incorrectos", + text: "Los campos introducidos son incorrectos. Numero de tarjeta debe ser de 16 números seguidos, CVV de 3 números" , icon: "error", }); } else { @@ -105,7 +105,7 @@ const Pago: FC = () => { Swal.fire({ title: "Precio Final", text: "El precio de los articulos es de " + parseado + " tras la suma" + - " con el precio de envío de " + envio + ". El precio Final que se " + + " con el precio de envío de " + envio + ". Tras realizar los calculos con el IVA (21%), el precio Final que se " + " deberá abonar es de: " + (precioFinal*1.21).toFixed(2), icon: "warning", confirmButtonColor: '#3085d6', @@ -272,13 +272,13 @@ const Pago: FC = () => { /> - Dirección de envío, por favor ingrese el nombre de su POD + Introduzca su Inrupt ID para poder seleccionar la direccion de envío ({ - [`&.${tableCellClasses.head}`]: { - backgroundColor: "#1976d2", - color: theme.palette.common.white, - }, - [`&.${tableCellClasses.body}`]: { - fontSize: 14, - }, -})); - -function getUserId(): string { - var id; - if(localStorage.getItem('token') != null) - var user:any = jwt_decode(localStorage.getItem('token') || '{}'); - id = user.id - return id -} - -const OrderHistory = () => { - const [ordersEmail, setOrdersEmail] = React.useState([]); - let [email, setEmail] = useState('') - let [id, setId] = useState('') - let [user, setUser] = React.useState({_id: "", name: "",email: "",surname: "", password: ""}); - - setId(getUserId()) - - const getUser = async (id:String) => { - const apiEndPoint= process.env.REACT_APP_API_URI || 'http://localhost:5000' - const data = await axios.get(apiEndPoint + "/user/findById/" + id).then ( - res => { - setUser(res.data); - return res.data - } - ) - return data != null; - } - - getUser(id) - setEmail(user.email) - - async function cargarPedidosEmail() { - setOrdersEmail(await getOrdersByEmail(email)) - } - cargarPedidosEmail() - - return ( -
-
- - - - - Código del pedido - Fecha de orden - Precio del pedido - Productos - - - - - -
-
-
-
- ); -} -export default OrderHistory; \ No newline at end of file diff --git a/webapp/src/pages/user/OrderUser.tsx b/webapp/src/pages/user/OrdersByUser.tsx similarity index 89% rename from webapp/src/pages/user/OrderUser.tsx rename to webapp/src/pages/user/OrdersByUser.tsx index 41b843d..f9e598d 100644 --- a/webapp/src/pages/user/OrderUser.tsx +++ b/webapp/src/pages/user/OrdersByUser.tsx @@ -6,7 +6,7 @@ type OrderProps = { orders: Order[] } -const OrderUser = (order: OrderProps) => { +const OrdersByUser = (order: OrderProps) => { return ( @@ -18,7 +18,7 @@ const OrderUser = (order: OrderProps) => { {o.fecha.toLocaleString().substring(0, 10)} {o.precioTotal} - {o.products.map((p) => {return p.nombre + " (" + 0 + " uds) "})} + {o.products.map((p) => {return p.nombre + " (" + p.stock + " uds) "})} ); @@ -27,4 +27,4 @@ const OrderUser = (order: OrderProps) => { ); } -export default OrderUser; \ No newline at end of file +export default OrdersByUser; \ No newline at end of file diff --git a/webapp/src/pages/user/OrdersHistoryByUser.tsx b/webapp/src/pages/user/OrdersHistoryByUser.tsx new file mode 100644 index 0000000..2694fce --- /dev/null +++ b/webapp/src/pages/user/OrdersHistoryByUser.tsx @@ -0,0 +1,79 @@ +import React, { FC } from 'react'; +import Table from '@mui/material/Table'; +import { TableContainer, TableHead} from '@mui/material'; +import TableBody from '@mui/material/TableBody'; +import TableCell, { tableCellClasses } from '@mui/material/TableCell'; +import TableRow from '@mui/material/TableRow'; +import { styled } from '@mui/material/styles'; +import { Order, User } from '../../shared/shareddtypes'; +import Paper from '@mui/material/Paper'; +import OrderAdmin from '../admin/OrderAdmin'; +import { getOrdersByEmail } from '../../api/api'; +import { useState } from 'react'; +import { getUserById } from '../../api/ApiUsers'; +import jwt_decode from "jwt-decode"; + +const StyledTableCell = styled(TableCell)(({ theme }) => ({ + [`&.${tableCellClasses.head}`]: { + backgroundColor: "#1976d2", + color: theme.palette.common.white, + }, + [`&.${tableCellClasses.body}`]: { + fontSize: 14, + }, +})); + +const OrdersHistoryByUser: FC = () => { + + const [orders, setOrders] = React.useState([]); + const [currentUser, setCurrentUser] = useState(); + + async function usuarioActivo(){ + + if(localStorage.getItem('token') != null){ + let id; + var user:any = jwt_decode(localStorage.getItem('token') || '{}'); + if(user) + id = user.id; + setCurrentUser(await getUserById(id)); + } + } + + async function pedidosUssuario() { + usuarioActivo() + let email = currentUser?.email; + if(email !== undefined) + setOrders(await getOrdersByEmail(email)); + } + + pedidosUssuario() + + return ( + +
+
+ + + + + Código + Fecha + Correo del comprador + Precio Compra (€) + Productos Comprado (Unidades) + + + + + + +
+
+
+
+ + ); + +} + +export default OrdersHistoryByUser; diff --git a/webapp/src/tests/Pago.test.tsx b/webapp/src/tests/Pago.test.tsx index aab33fc..8160326 100644 --- a/webapp/src/tests/Pago.test.tsx +++ b/webapp/src/tests/Pago.test.tsx @@ -4,6 +4,6 @@ import Pago from '../pages/Pago'; test('Ventana Pago', async () => { render() expect(screen.getByText(/Comprueba tu direccion/i)).toBeInTheDocument(); - expect(screen.getByText(/Dirección de envío, por favor ingrese el nombre de su POD/i)).toBeInTheDocument(); + expect(screen.getByText(/Introduzca su Inrupt ID para poder seleccionar la direccion de envío/i)).toBeInTheDocument(); });