Este un simple ejemplo de una tienda realizada siguiendo los desafíos planteados por Coderhouse, la idea del repo es que tengan un ejemplo de lo que van a poder hacer al terminar el curso, también para que les sirva como consulta en los momentos en que se sientan perdidos o trabados con los desafíos. RECUERDEN POR SU BIEN NO ENTRAR AL REPO SALVO QUE SEA NECESARIO. NO COPIEN ESTO MISMO EN SUS PROYECTOS. INVESTIGAR Y CONSULTAR SON HERRAMIENTAS FUNDAMENTALES DE CUALQUIER BUEN DESARROLLADOR Y ESTAS NO SE INCLUYEN EN EL CURSO, QUEDA EN USTEDES APRENDER A RESOLVER LOS PROBLEMAS CON LOS QUE SE ENCUENTREN AL ESTAR PROGRAMANDO.
El proyecto fue realizado de una forma simple, apoyándome en algunas librerías para facilitar el desarrollo y dejando de lado el diseño y el responsive del proyecto. Solo me dediqué al desarrollo funcional de los desafíos. ACLARACIÓN: No es necesario usar todas las librerías que utilice, presten atención a cuales son las obligatorias y necesarias y cuales fueron opcionales.
- El proyecto cuenta con una branch master donde se encuentra la versión productiva de la tienda y esta deployada en vercel baja esta url
- El proyecto cuenta con una branch dev donde se encuentran los últimos cambios realizados en el proyecto.
- El proyecto cuenta con una branch por cada desafío realizado que cuenta con el código necesario para cumplir con los requisitos del mismo.
- react-router: Librería para el ruteo de la SPA.
- firebase: Servicio web que nos proporciona un backend en la nube con una fuente de datos NoSQL.
- grommet: Librería UI de componentes
- grommet-icons: Librería de Iconos
- eslint y eslint-config-xo: Linter del proyecto
- husky y lint-staged: Librerías para ejecutar acciones antes de un commit
- prop-types: Librería para el tipado de las props de los componentes
Consigna:
Crea una aplicación utilizando el CLI con el nombre de tu tienda, y ejecuta los comandos necesarios para instalar React, configurarlo y visualizarlo en tu navegador.
Aspectos a incluir en el entregable:
- Link al repositorio de github
- Dentro del repositorio, deberían encontrarse las carpetas y los archivos src, README.md y package.json, entre otros
Material de referencia:
Clase 2: INSTALACIÓN Y CONFIGURACIÓN DEL ENTORNO
Resumen:
- Se crea el repositorio del proyecto
- Se crea el branch feature/Desafio-01
- Se instala node.js - v16.13.0
- Se crea el proyecto de React utilizando create-react-app
Consigna:
En el directorio de tu proyecto, crea una carpeta dentro de src llamada “components”, que contenga a NavBar.js para crear una barra de menú simple.
Aspectos a incluir en el entregable:
Crea una carpeta dentro de src llamada components que contenga a NavBar.js para crear una barra de menú simple, que tenga:
- Brand (título/nombre de la tienda)
- Un listado de categorías clickeables
- Incorpora alguna librería de estilos con bootstrap/materialize u otro de tu preferencia (opcional).
Material de referencia:
Clase 3: JSX Y WEBPACK
Resumen:
- Se instala Grommet como librería de UI del proyecto. Storybook
- Se instala icons-grommet como librería de iconos del proyecto.
- Se instala eslint y xo como linter del proyecto.
- Se instala lint-staged y husky.
- Se crea el fichero /components y dentro el componente Navbar.
- Se crea el fichero /assets y dentro /images donde se guardan las imágenes del proyecto.
- Se crea el fichero /utils donde se colocan archivos de utilería.
Consigna:
- Crea un componente CartWidget.js con un ícono, y ubícalo en el navbar. Agrega algunos estilos con bootstrap/materialize u otro.
- Crea un componente contenedor ItemListContainer.js con una prop greeting, y muestra el mensaje dentro del contenedor con el styling integrado.
Aspectos a incluir en el entregable:
- Parte 1: crea un componente CartWidget.js que haga rendering de un ícono Cart, e inclúyelo dentro de NavBar.js para que esté visible en todo momento.
- Parte 2: crea un componente ItemListContainer. Impórtalo dentro de App.js, y abajo de NavBar.js.
Material de referencia:
Clase 4: COMPONENTES I
Resumen:
- Se crea el componente CartWidget y se importa en el componente Navbar
- Se crea el componente ItemListContainer y se importa en el componente App, se pasa un mensaje por props
- Se instala la libreria PropTypes para manejar el tipado de las props del proyecto.
Consigna:
- Crea un componente ItemCount.js, que debe estar compuesto de un botón y controles, para incrementar y decrementar la cantidad requerida de ítems.
Aspectos a incluir en el entregable:
- Componente ItemCount.js con los respectivos controles de la consigna.
A tener en cuenta:
- El número contador nunca puede superar el stock disponible
- De no haber stock el click no debe tener efecto y por ende no ejecutar el callback onAdd
- Si hay stock al clickear el botón se debe ejecutar onAdd con un número que debe ser la cantidad seleccionada por el usuario.
Detalle importante: Como sabes, todavía no tenemos nuestro detalle de ítem, y este desarrollo es parte de él, así que por el momento puedes probar e importar este componente dentro del ItemListContainer, sólo a propósitos de prueba. Después lo sacaremos de aquí y lo incluiremos en el detalle del ítem.
Material de referencia:
Clase 5: COMPONENTES II
Resumen:
- Se crea el componente ItemCount
- Se importa el componente ItemCount en ItemListContainer y se le pasan las props: stock y onAdd
- Se utiliza dos veces con diferentes valores de stock para corroborar la independencia de ambos componentes.
Consigna:
- Crea los componentes Item.js e ItemList.js para mostrar algunos productos en tu ItemListContainer.js. Los ítems deben provenir de un llamado a una promise que los resuelva en tiempo diferido (setTimeout) de 2 segundos, para emular retrasos de red
Aspectos a incluir en el entregable:
- Item.js: Es un componente destinado a mostrar información breve del producto que el user clickeará luego para acceder a los detalles (los desarrollaremos más adelante)
- ItemList.js Es un agrupador de un set de componentes Item.js (Deberías incluirlo dentro de ItemListContainer del desafío 3)
- Implementa un async mock (promise): Usa un efecto de montaje para poder emitir un llamado asincrónico a un mock (objeto) estático de datos que devuelva un conjunto de item { id, title, description, price, pictureUrl } en dos segundos (setTimeout), para emular retrasos de red.
Material de referencia:
Clase 6: PROMISES, ASINCRONÍA Y MAP
Resumen:
- Se agrega el favicon de Citrix
- Se agrega un enfoque de token para el precio de los productos 😋
- Se crea el componente Item y el componente ItemList
- Se crea el fichero /mocks con el archivo data donde se encuentra el listado de productos.
- Se movieron las imágenes de los productos al fichero /mocks (las imágenes van a estar en la firebase al finalizar el desarrollo)
- Se importa el componente Item dentro del componente ItemList
- Se importa el componente ItemList dentro del componente ItemListContainer
- Se simula la carga de los productos del mock utilizando promesas en el componente ItemListContainer.
- Se comprimien las imágenes usando tinypng
Consigna:
- Crea tu componente ItemDetailContainer, con la misma premisa que ItemListContainer.
Aspectos a incluir en el entregable:
- Al iniciar utilizando un efecto de montaje, debe llamar a un async mock, utilizando lo visto en la clase anterior con Promise, que en 2 segundos le devuelva un 1 ítem, y lo guarde en un estado propio.
Consigna:
- Crea tu componente ItemDetail.js.
Aspectos a incluir en el entregable:
- ItemDetail.js, que debe mostrar la vista de detalle de un ítem incluyendo su descripción, una foto y el precio.
Material de referencia:
Clase 7: CONSUMIENDO API’S
Resumen:
- Se crea el componente ItemDetailContainer
- Se crea el componente ItemDetail
- Se importa el componente ItemDetail en ItemDetailContainer
- Se simula la carga de un producto del mock utilizando promesas en el componente ItemDetailContainer.
- Se crea el componente Spinner (opcional) y se usa en ItemDetailContainer y en ItemListContainer
- Se mueve la logica de handleIconByCategory en Item a un custom hook en el fichero /hook y en el archivo useLogoCategory
- Se implementa el useLogoCategory en Item, ItemDetail y Navbar
Consigna:
- Configura en App.js el routing usando un BrowserRouter de tu aplicación con react-router-dom
Aspectos a incluir en el entregable:
- Rutas a configurar
- ‘/’ navega a
<ItemListContainer />
- ‘/category/:id’
<ItemListContainer />
- ‘/item/:id’ navega a
<ItemDetailContainer />
- Links a configurar
- Clickear en el brand debe navegar a ‘/’
- Clickear un Item.js debe navegar a /item/:id
- Clickear en una categoría del navbar debe navegar a /category/:categoryId
- Para finalizar integra los parámetros de tus async-mocks para reaccionar a :itemId y :categoryId ¡utilizando efectos y los hooks de parámetros que vimos en clase! Si te encuentras en una categoría deberías poder detectar la navegación a otra categoría y volver a cargar los productos que correspondan a dicha categoría
Además:
- Deberás corroborar que tu proyecto cuente con:
- Navbar con cart
- Catálogo
- Detalle de producto
- Incluir:
- Archivo readme.md
A tener en cuenta:
- En la Rúbrica de Evaluación (ubicada en la carpeta de la camada) encontrarás un mayor detalle respecto a qué se tendrá en cuenta para la corrección.
Importante:
- La entrega intermedia no supone la realización de un archivo aparte o extra; marca que en este momento se hará una revisión más integral
Material de referencia:
Clase 8: ROUTING Y NAVEGACIÓN
Resumen:
- Se instala la librería react-router-dom y history.
- Se inicializa el BrowserRouter en el src/index.js
- Se agrega las rutas en el archivo src/App.jsx
- Se crea el fichero /routes y dentro los page components Home y Product.
- Se acomodan los componentes de App.jsx en los page components Home y Product.
- Se crea el componente Layout el cual incluirá los componentes Navbar y Footer de la app.
- Se actualiza el mock del componente Navbar con las rutas correctas.
- Se usa el hook useParams en el componente ItemListContainer y se crea la función handleFilterData() para filtrar los ítems del mock por categoría.
- Se usa el hook useNavigate en el componente Item para navegar al page component Product pasando como parámetro el id del item.
- Se usa el hook useParams en el componente ItemDetailContainer y se crea la funcion handleFilterData() para filtrar los ítems del mock por id del item.
- Se usa el hook useNavigate en el componente Navbar para navegar siempre a la Home
- Se crea el componente 404 y se configura la ruta por defecto
Consigna:
- Importa el ItemCount.js del desafío Nº 4 en el counter ItemDetail.js, y configura el evento de compra, siguiendo los detalles de manual.
Aspectos a incluir en el entregable:
- Debes lograr separar la responsabilidad del count, del detalle del ítem, y esperar los eventos de agregado emitidos por el ItemCount
- Cuando ItemCount emita un evento onAdd almacenarás ese valor en un estado interno del ItemDetail para hacer desaparecer el ItemCount
- El botón de terminar mi compra debe poder navegar a un componente vacío por el momento en la ruta ‘/cart’.
Material de referencia:
Clase 9: EVENTOS
Resumen:
- Se crea un estado count dentro del componente ItemDetail usando el hook useState donde se guarda el valor obtenido desde ItemCount
- Se condiciona para mostrar el ItemCount o un boton que redirecciona al page component Cart si dependiendo del valor de count
- Se crea un nuevo page component llamado Cart
Consigna:
- Implementa React Context para mantener el estado de compra del user, siguiendo los detalles del manual.
Aspectos a incluir en el entregable:
- Al clickear comprar en ItemDetail se debe guardar en el CartContext el producto y su cantidad en forma de objeto { name, price, quantity, etc. } dentro del array de productos agregados
Detalle importante:
- CartContext debe tener la lógica incorporada de no aceptar duplicados y mantener su consistencia.
Métodos recomendados:
- addItem(item, quantity) // agregar cierta cantidad de un ítem al carrito
- removeItem(itemId) // Remover un item del cart por usando su id
- clear() // Remover todos los items
- isInCart: (id) => true|false
Material de referencia:
Clase 10: CONTEXT
Resumen:
- Se crea el fichero /context y dentro el archivo CartContext.js
- Se inicializa el CartContextProvider en index.js
- Se crea en el CartContext los siguientes métodos: addItem, removeItem, clear, isInCart y algunos extras.
- Se implementa el addItems en el componente ItemDetail y se prueba usando un log por consola.
Consigna:
- Expande tu componente Cart.js con el desglose de la compra, y actualiza tu CartWidget.js para hacerlo reactivo al contexto.
Aspectos a incluir en el entregable:
Cart.js
- Debe mostrar el desglose de tu carrito y el precio total.
- Debe estar agregada la ruta ‘cart’ al BrowserRouter.
- Debe mostrar todos los ítems agregados agrupados.
- Por cada tipo de ítem, incluye un control para eliminar ítems.
- De no haber ítems muestra un mensaje, de manera condicional, diciendo que no hay ítems y un react-router Link o un botón para que pueda volver al Landing (ItemDetailContainer.js) para buscar y comprar algo.
CartWidget.js
- Ahora debe consumir el CartContext y mostrar en tiempo real (aparte del ícono) qué cantidad de ítems están agregados (2 camisas y 1 gorro equivaldrían a 3 items).
- El cart widget no se debe mostrar más si no hay items en el carrito, aplicando la técnica que elijas (dismount, style, etc).
- Cuando el estado interno de ItemDetail tenga la cantidad de ítems solicitados mostrar en su lugar un botón que diga “Terminar mi compra”
Material de referencia:
Clase 11: RENDERIZADO CONDICIONAL
Resumen:
- Se implementa el CartContext en el componente CartWidget para mostrar el total de items en tiempo real.
- Se crea el componente ItemCart el cual muestra la info del item en el carrito junto a las acciones de eliminar 1 elemento del carrito como todos los de ese tipo.
- Se crea el page component Cart donde se muestra los items dentro del CartContext junto a los botones que ejecutan las diferentes acciones.
Consigna:
- Conecta tu nueva ItemCollection de Google Firestore a tu ItemListContainer y ItemDetailContainer
Aspectos a incluir en el entregable:
- Conecta tu colección de firestore con el listado de ítems y con el detalle de ítem.
- Elimina los async mocks (promises) y reemplazalos por los llamados de Firestore.
- Si navegas a /item/:id, debe ocurrir una consulta de (1) documento.
- Si navegas al catálogo, debes consultar (N) documentos con un query filtrado, implementando la lógica de categorías y obteniendo el id de categoría del parámetro de react-router :categoryId.
Material de referencia:
Clase 12: FIREBASE I
Resumen:
- Se crea un proyecto en firebase
- Se instala la libreria de firebase en el proyecto
- Se crea el fichero /firebase y el archivo client.js donde se importa firebase y se inicializa
- Se carga el mock como una coleccion de firebase llamada products
- Se creo un nuevo contexto para los productos (ProductContext.js)
- Se eliminaron las promesas y los fetchs que simulaban la carga de datos desde el mock y se implementan los metodos de firebase en los componentes ItemListContainer y tambien en ItemDetailContainer.
Consigna:
- Crea tu colección de órdenes.
Aspectos a incluir en el entregable:
- Utiliza las operaciones de inserción para insertar tu orden en la colección y dale al user su id de orden auto-generada
- Crea los mappings para poder grabar un objeto del formato { buyer: { name, phone, email }, items: [{ id, title, price }], date, total }
- Pista: Puedes controlar los stocks con multi-gets utilizando los itemId de tu cart.
Material de referencia:
Clase 13: FIREBASE II
Resumen:
- Se crean nuevos metodos en firebase/client.js para una nueva orden y para actualizar el stock de los productos.
- Se crea un nuevo page component para la ThankYou page.
- Se crea un simple formulario en el componente CartContainer.
- Se crea una nueva orden luego de completar el form con los productos agregados al carrito y se redirecciona a la ThankYou page donde se muestra el numero de la orden.
- Se actualiza el stock de los productos antes de generar una nueva orden.
Resumen:
- Se agrega un componente Carousel para mostrar los banners
- Se crea el componente Footer y se agrega al componente Layout
- Se crea una funcionalidad extra en firebase/client.js para resetear el valor del stock de los productos a 20
- Refactor de componentes y estilos.
- Se crea un ejemplo de autentificacion con firebase y Github.