diff --git a/restapi/api.ts b/restapi/api.ts index e30f2f8..2bd3fd9 100644 --- a/restapi/api.ts +++ b/restapi/api.ts @@ -1,9 +1,11 @@ import express, { Request, Response, Router } from 'express'; import { check } from 'express-validator'; //import mongoose from 'mongoose'; -import { IProducto, Producto } from './modelos/productoModelo'; +import { IProducto } from './modelos/productoModelo'; +import { IUsuario } from './modelos/usuarioModelo'; const Productos = require('./modelos/productoModelo'); +const Usuarios = require('./modelos/usuarioModelo'); const mongoose = require('mongoose'); const api: Router = express.Router(); @@ -37,6 +39,20 @@ api.post( } ); +api.get( + "/users/login/:user/:pass", + async (req: Request, res: Response): Promise => { + var user:string = req.params.user; + var pass:string = req.params.pass; + const usuario: IUsuario = await Usuarios.findOne( {username: user, password: pass} ); + if (usuario) { + return res.status(200).send(usuario); + } else { + return res.status(404).json({ message: 'El usuario con nombre "${user}" no se ha encontrado.' }); + } + } +) + api.get( "/products/list", async (req: Request, res: Response): Promise => { diff --git a/restapi/modelos/usuarioModelo.ts b/restapi/modelos/usuarioModelo.ts new file mode 100644 index 0000000..2db2672 --- /dev/null +++ b/restapi/modelos/usuarioModelo.ts @@ -0,0 +1,38 @@ +import mongoose, { ObjectId } from 'mongoose'; + +export interface IUsuario { + username:String; + password:String; +} + +interface UsuarioDoc extends mongoose.Document { + _id: ObjectId; + username:String; + password:String; +} + +interface UsuarioModelInterface extends mongoose.Model { + build(attr: IUsuario): UsuarioDoc +} + +const usuarioSchema = new mongoose.Schema({ + username: { + type: String, + required: true, + trim: true + }, + password: { + type: String, + required: true, + trim: true + } +}) + +usuarioSchema.statics.build = (attr: IUsuario) => { + return new Usuario(attr) +} + +const Usuario:UsuarioModelInterface = mongoose.model('Usuario',usuarioSchema) + +export default Usuario + diff --git a/restapi/rutas/productoRutas.ts b/restapi/rutas/productoRutas.ts index 7f90021..b9c47e3 100644 --- a/restapi/rutas/productoRutas.ts +++ b/restapi/rutas/productoRutas.ts @@ -125,16 +125,15 @@ router.get('/producto/detalles/:referencia', async (req: Request, res: Response) //Realizamos la busqueda por referencia const product = await Producto.findOne({referencia: ref}) if(product){ - let entrada = product; + let entrada:ProductoDoc = product; let salida: TypeProduct = ({ _objectId: entrada._id, id: "", nombre:"",precio:0,descripcion:"",imagen: "" }); salida.id = entrada.referencia; salida.nombre = entrada.marca + " " +entrada.modelo; salida.precio = entrada.precio salida.descripcion = entrada.descripcion; - //Recuperamos la imagen principal asociada a este producto - const foto = await consultarREST(URL_BASE +'foto/' + entrada.id) ; - if (foto.length != 0) - salida.imagen = foto[0].ruta + + if (entrada.fotos.length != 0) + salida.imagen = entrada.fotos[0].ruta; else salida.imagen = "" //buscar una imagen por defecto si no hay principal resultado.push(salida) diff --git a/restapi/rutas/usuarioRutas.ts b/restapi/rutas/usuarioRutas.ts new file mode 100644 index 0000000..dbef0e7 --- /dev/null +++ b/restapi/rutas/usuarioRutas.ts @@ -0,0 +1,34 @@ +import express, { Request, Response } from 'express'; +import Usuario from '../modelos/usuarioModelo'; +import "dotenv/config"; +import {User} from '../../webapp/src/shared/shareddtypes'; + +//Obtenemos la url de la apirest de Heroku o utilizamos localhost por defecto +let URL_BASE:string = `${process.env.API_REST_URL_BASE_LOCAL}` +if(process.env.PORT) { + URL_BASE = `${process.env.API_REST_URL_BASE_HEROKU}` +} + +const router = express.Router() + +router.get('/users/login/:username/:password', async (req: Request, res: Response) => { + let resultado:User[] = new Array(); + //Parametros + const paramUser:string = req.params.username; + const paramPass:string = req.params.password; + //Realizamos la busqueda por referencia + const user = await Usuario.findOne({username: paramUser, password: paramPass}) + if(user){ + let entrada = user; + let salida: User = ({ username: "", password:""}); + salida.username = entrada.username.toString(); + salida.password = entrada.password.toString(); + resultado.push(salida); + return res.status(200).send(resultado); + } else{ + return res.status(500).json(); + } + +}) + +export { router as usuarioRouter } \ No newline at end of file diff --git a/restapi/server.ts b/restapi/server.ts index e5e8e66..53d7b51 100644 --- a/restapi/server.ts +++ b/restapi/server.ts @@ -3,6 +3,7 @@ import cors from "cors"; import mongoose from 'mongoose'; import { json } from 'body-parser'; import { productoRouter } from './rutas/productoRutas'; +import { usuarioRouter } from './rutas/usuarioRutas'; import { fotoRouter } from './rutas/fotoRutas'; import { tallaRouter } from './rutas/tallaRutas'; import "dotenv/config"; @@ -14,6 +15,7 @@ app.use(cors()) app.use(productoRouter) app.use(fotoRouter) app.use(tallaRouter) +app.use(usuarioRouter) mongoose .connect(`${process.env.MONGODB_URI}`, { diff --git a/webapp/src/api/api.ts b/webapp/src/api/api.ts index a1b9797..f7cda09 100644 --- a/webapp/src/api/api.ts +++ b/webapp/src/api/api.ts @@ -25,6 +25,18 @@ export async function getUsers():Promise{ return response.json() } +/* +* Metodo que utilizaremos para comprobar si el usuario que intenta logearse, existe en base de datos. +*/ +export async function getUser(username : string, password : string): Promise { + const apiPetition:string = apiEndPoint+'users/login/' + username + '/' + password; + const response:Response = await fetch(apiPetition); + if(response.status == 500) { + return null; + } + return response.json(); +} + export async function getProducts(): Promise { const response:Response = await fetch(apiEndPoint+'products/list'); return response.json(); diff --git a/webapp/src/components/Details/RightDetails.tsx b/webapp/src/components/Details/RightDetails.tsx index e178ec5..8640a9a 100644 --- a/webapp/src/components/Details/RightDetails.tsx +++ b/webapp/src/components/Details/RightDetails.tsx @@ -27,23 +27,20 @@ type parsedProduct = { const RightDetails = (parsed:parsedProduct) => { function addToCart(){ + // Objeto a almacenar const item = {"_objectId":parsed.product[0]._objectId,"id":parsed.product[0].id,"nombre":parsed.product[0].nombre,"precio":parsed.product[0].precio,"imagen":parsed.product[0].imagen}; + // Sacamos el carrito almacenado en sesion var cart:string = sessionStorage.getItem('cart') as string; - if(JSON.parse(cart).length > 0){ + + // Si el carrito NO esta vacio, añadimos el nuevo item al final + if(JSON.parse(cart).length > 0){ var newCart:string = cart.substring(0, cart.length-1) + ',' + JSON.stringify(item) + ']'; - } else{ + } + // Si no, introducimos el primer item a nuestro carrito + else{ var newCart:string = cart.substring(0, cart.length-1) + JSON.stringify(item) + ']'; } sessionStorage.setItem('cart', newCart); - var usuario:string = sessionStorage.getItem('user') as string; - const [nombre,pas]=usuario.split(","); - const[u,username]=nombre.split(":") - const[p,password]=pas.split(":") - if(usuario!=undefined){ - let item2 = {"username":username,"password":password, "cart":sessionStorage.getItem('cart') as string}; - sessionStorage.setItem('user',JSON.stringify(item2)); - var Comprueba:string = sessionStorage.getItem('user') as string; - } alert("Artículo: \"" + parsed.product[0].nombre + "\" añadido al carrito."); } diff --git a/webapp/src/components/Fragments/Nav.tsx b/webapp/src/components/Fragments/Nav.tsx index 574b43c..0fedf1a 100644 --- a/webapp/src/components/Fragments/Nav.tsx +++ b/webapp/src/components/Fragments/Nav.tsx @@ -44,7 +44,7 @@ export default function MenuAppBar() { }; const {session, logout} = useSession(); - const usuario = JSON.parse(sessionStorage.getItem('user') as string); + const usuario = sessionStorage.getItem('user'); return ( diff --git a/webapp/src/components/Home/List.tsx b/webapp/src/components/Home/List.tsx index e6d8a96..acef9d6 100644 --- a/webapp/src/components/Home/List.tsx +++ b/webapp/src/components/Home/List.tsx @@ -74,32 +74,32 @@ const useStyles = makeStyles({ const itemData = [ { - img: 'https://i.blogs.es/67332d/screenshot_4501/original.jpeg', + img: 'https://i.imgur.com/cyhVYVf.jpg', title: 'Pokemon', featured: true, }, { - img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTviEWtiJBnAfMBudW5kmrIpt9tng4cD2_F_w1HDAnVAcnqoP5LJM9vKNBOBlrvSigJEIM&usqp=CAU', + img: 'https://i.imgur.com/VwtfVgU.jpg', title: 'Zapatillas Baby Yoda', author: '@rollelflex_graphy726', }, { - img: 'https://images.ecestaticos.com/Xt-KJxmVpvzrqtKT8eEnRNxbcTc=/51x0:1249x899/1200x900/filters:fill(white):format(jpg)/f.elconfidencial.com%2Foriginal%2F9c2%2F2d6%2F83d%2F9c22d683d9536e8961c5d4fe8a2f6f4f.jpg', + img: 'https://i.imgur.com/1jWaZbp.jpg', title: 'Style', author: '@helloimnik', }, { - img: 'https://images-eu.ssl-images-amazon.com/images/G/30/AMAZON-FASHION/2021/FASHION/FEATURE_PAGES/SNEAKERS/MENS/04_C12x.jpg', + img: 'https://i.imgur.com/d864pTb.jpg', title: 'Caña Alta', author: '@nolanissac', }, { - img: 'https://ichef.bbci.co.uk/news/640/cpsprodpb/B9FF/production/_117751674_satan-shoes1.jpg', + img: 'https://i.imgur.com/C4fhmzn.jpg', title: 'Lo último', author: '@hjrc33', }, { - img: 'https://www.clara.es/medio/2019/02/28/zapatillas-negras-vans-85%E2%82%AC_482707a2_1000x1500.jpg', + img: 'https://i.imgur.com/nZGVoea.jpg', title: 'Casual', author: '@arwinneil', featured: true, diff --git a/webapp/src/components/Home/Shoes.tsx b/webapp/src/components/Home/Shoes.tsx index ee70303..d5b7f8c 100644 --- a/webapp/src/components/Home/Shoes.tsx +++ b/webapp/src/components/Home/Shoes.tsx @@ -80,7 +80,7 @@ const ShoesView = (parsed : ProductsParsed) => { refreshProductos(); },[]); function filterFunction(texto: any) { - var filter; + var filter:TypeProduct[]; if(texto==""){ filter=parsed.products; } diff --git a/webapp/src/components/Login/LoginUsrPsswd.tsx b/webapp/src/components/Login/LoginUsrPsswd.tsx index 61c8ab9..bacd195 100644 --- a/webapp/src/components/Login/LoginUsrPsswd.tsx +++ b/webapp/src/components/Login/LoginUsrPsswd.tsx @@ -9,6 +9,7 @@ import Button from '@material-ui/core/Button'; import { Link, Typography } from "@mui/material"; import Nav from '../Fragments/Nav'; import { User } from '../../shared/shareddtypes'; +import { getUser } from '../../api/api'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -41,11 +42,22 @@ const Login = () => { const classes = useStyles(); const [userName,setUserName]=useState(""); const [password,setPassword]=useState(""); - - function addUserToSession(){ - //IR A LA BASE DE DATOS - let item = {"username":userName,"password":password, "cart":sessionStorage.getItem('cart') as string}; - sessionStorage.setItem('user',JSON.stringify(item)); + + async function addUserToSession(){ + //Comprobamos los credenciales introducidos en base de datos + var user = (await getUser(userName, password)); + if(user==null){ + // Usuario no encontrado + alert('Credenciales incorrectas.'); + } else { + // Usuario encontrado en base de datos + var parsedUser:User = (user as unknown as Array)[0]; + console.log(parsedUser.username); + // Lo guardamos en sesion (solo el usuario, la contraseña no la necesitamos para nada) + sessionStorage.setItem('user', parsedUser.username); + // Redirigimos a inicio + window.location.href='http://localhost:3000/'; + } } return ( <>