La arquitectura del proyecto se separa entre las carpetas containers y components.
La idea es que los containers contengan las rutas/páginas de la aplicación y que contengan la mayor parte de lógica de estas como por ejemplo dispatches, manejadores de eventos, pequeñas transformaciones, etc.
Por otras partes la carpeta de components es contener todos aquellos componentes que se encargan de renderizar la información, sin ningún tipo de lógica.
Este proyecto contiene redux para manejar el estado global de la aplicación. Está separado en la carpeta actions, reducers y el fichero store.js.
El archivo store.js contiene todos los reducers de la aplicación donde se almacena todo. En este caso existe un estado global para la parte de autentificación y otra con los datos de las campañas.
En la carpeta actions guardamos los métodos que disparan eventos mediante el hook dispatch, estos pueden ser llamadas al api o cambios que queramos guardar dentro de nuestro estado global de la aplicación.
En el caso de llamadas al api, los request devuelven un payload que será interceptado en el fichero interceptors/config.js donde se alimentará el estado de la llamada mediante _SUCCESS o _FAIL para detectar si la llamada realizada ha sido un éxito o un fallo. Esta estrategia permite poder manejar el estado de cada llamada añadiendo lógicas asíncronas de forma sencilla.
La forma que tenemos de conectar los actions y los reducers es mediante la clave type que definimos en action y que coincide en el reducer.
Una vez tenemos definidos los actions y el reducer que maneja el estado, utilizamos el hook useSelector()
para consultar el campo que queremos dentro de nuestro container.
Es posible que nos surja la duda de si realizar la consulta desde los componentes o desde los containers, en este caso yo prefiero hacer toda esa lógica en los containers y pasar los datos hacia los hijos para intentar tener la mayor lógica posible en los contendores.
En algunos casos, para intentar que los datos lleguen al contendor de la forma más sencilla posible se pueden utilizar funciones o métodos de transformación para que, antes de guardarlos en el estado de la aplicación, tengan una estructura más sencilla de leer.
Es el caso que tenemos en el fichero reducers/campaigns.js
donde el método transformProjectsToTable
recibe la llamada del api y lo formatea para que tenga la estructura que demanda la tabla del detalle de campaña.
En un caso ideal, el api debería de devolver la mejor estructura posible para el frontend, pero como digo es un caso bastante común que necesitemos un formato que nos facilite el renderizado.
Si bien esta transformación la podríamos hacer en los contenedores creo que esta estrategia nos puede ayudar a que los contenedores queden lo más limpios posibles.
Los estilos de la aplicación estan realizados con el styled-components de forma global existe un tema definido en la carpeta theme y que se puede usar dentro de cualquier componente estilado, pudiendo añadir lógicas de javascript dentro de cada uno de ellos mediante props.
A nivel de arquitectura los estilos se mantienen dentro del mismo archivo, sería posible separarlos aunque prefiero que todo esté en el mismo fichero para que el mantenimiento sea más sencillo.
Si un archivo se hace demasiado grande y crece en líneas lo ideal sería hacer una separación para intentar que no crezcan demasiado.
Las traducciones se hacen de la misma forma que hacemos en los otros proyectos. En ese caso que querido mantener la misma metodolgía
Para instalar el proyecto podemos hacerlo mediante npm install
o yarn install
Para iniciar el proyecto podemos hacerlo mediante npm start
o yarn start