From fa729d295802b44e2406c92dff711608d80b3dbd Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 10:17:05 +0200 Subject: [PATCH 01/37] ref: #187 starting readme Spanish translation --- readme.md | 4 +- readme_es.md | 241 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 readme_es.md diff --git a/readme.md b/readme.md index 7625f920..26e45432 100644 --- a/readme.md +++ b/readme.md @@ -1,14 +1,14 @@ # React Typescript by sample The goal of this project is to provide a set of simple samples, providing and step by step guide to -start working with React and Typescript. +start working with React and TypeScript. We have incorporated a set of examples based on hooks. Right now you got two main folders: - [Hooks](./hooks): set of samples migrated to hooks (right now 15 samples migrated), if you are new to - React, or you are going to start working on a new project, I recommend you going through these + React, or you are going to start working on a new project, We recommend you going through these examples. - [Old_class_components_samples](./old_class_components_samples): The old samples, just in case you need to work with older react diff --git a/readme_es.md b/readme_es.md new file mode 100644 index 00000000..92401985 --- /dev/null +++ b/readme_es.md @@ -0,0 +1,241 @@ +# React Typescript - ejemplos + +El objetivo de este proyecto es ofrecer un set de ejemplos simples, proporcionando una guía paso a paso +para empezar a trabajar con React y TypeScript. + +Hemos incorporado un set de ejemplos basados en hooks. + +Ahora mismo hay dos carpetas principales: + +- [Hooks](./hooks): set de ejemplos migrados a hooks (ahora mismo 15 ejemplos), si eres nuevo en React, o vas a empezar a trabajar en +un nuevo proyecto, Te recomendamos que lo hagas a través de ´estos ejemplos. + +- [Old_class_components_samples](./old_class_components_samples): The old samples, just in case you need to work with older react + versions or you need to maintain legacy code. + +If you want to make a deeper dive on React Hooks you can check this repo [React Hooks By Example](https://github.com/Lemoncode/react-hooks-by-example) + +Other guided repos available (react / redux + typescript): + +- [Redux By Sample](https://github.com/Lemoncode/redux-by-sample) +- [From React to Redux](https://github.com/Lemoncode/from-react-to-redux-ts) +- [Redux Sagas](https://github.com/Lemoncode/redux-sagas-typescript-by-example) + +# Examples + +The goal of this project is to provide a set of simple samples, providing and step by step guide to +start working with React and Typescript. Characteristics: + +- Bundling based on webpack. +- React + Typescript based. +- Simple navigation using react-router. +- Managing async calls and updates. +- Using Redux library (not available yet on hooks version, coming soon). +- Handling async calls via Redux-Thunk + Redux Saga (not available yet on hooks version, coming soon) +- Adding unit testing support (not available yet on hooks version, coming soon). +- Implementing Lazy Loading (not available yet on hooks version, coming soon). +- ... + +## To get started: + +1. Install [NodeJS](http://www.nodejs.org) +2. Download this repo +3. Open the command line of your choice and cd to a sample directory within this repo on your machine +4. `npm install` - Installs packages +5. `npm start` - Builds the project and launch a lite web server (webpack-dev-server). +6. Navigate to [http://localhost:8080/](http://localhost:8080/) if your browser doesn't open automatically. + +# samples + +## Hooks + +### [00 Boiler plate](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/00_BoilerPlate) + +Bundling + npm start based on webpack. + +### [01 Hello React](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/01_HelloReact) + +Display the text 'Hello React'. + +Hello world, simples react render sample. + +### [02 Properties](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/02_Properties) + +Display the text 'Hello {name}' (where name is a prop +that contains a given name). + +Introduce a basic React concept, handling properties. + +### [03 State](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/03_State) + +Starting from sample 02, let's the user change the name to be displayed. + +Introduce a basic React concept, handling State using hooks. + +### [04 Callback](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/04_Callback) + +Starting from sample 03, let the user change the name only +when he hits a _change_ button. + +Using callbacks. + +### [05 Refactor](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/05_Refactor) + +Refactor sample 04, cleanup and discussion on where to place the state. + +Refactor the job done. + +### [06 Enable](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/06_Enable) + +Starting from sample 05, enable / disable the _change_ button +when the text is empty or same name as original name,. + +Enable/disable components. + +### [07 ColorPicker](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/07_ColorPicker) + +Simple color picker demo (show how properties work). + +### [08 ColorPicker Refactor](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/08_ColorPickerRefactor) + +ColorPicker refactor. + +### [09 Sidebar](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/09_Sidebar) + +Implementation of a single sidebar. + +### [10 Table Mock](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/10_TableMock) + +Render a table and use a child component to render each row, using mock data. + +### [11 Table Axios](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/11_TableAxios) + +Starting from sample 10, remove mock data, hit a real REST API (Github api), use +axios to perform the fetch call. + +### [12 React Router](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/12_ReactRouter) + +Starting from sample 03,start using React-Router (SPA navigation). + +### [13 Login Form](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) + +Starting from sample 12, implement a basic login page, that will redirect the user to another page whenever the login has completed successfully. + +### [14 Form Validation](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) + +Starting from sample 13, add validation support to login form. + +### [15 Context](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/15_Context) + +Starting from sample 14, learn how React 16 context api works. + +## Old Class folder + +### 00 Boiler plate + +Bundling + npm start based on webpack. + +### 01 Hello React + +Hello world, simples react render sample. + +### 02 Components + +Creating a common header and about page react components. + +### 03 Navigation + +Creating a "members" page, adding navigation using react-router. + +### 04 Display data + +Create a read only list component (table >> tr >> td), reading list of members +from a fake api and dumping it into component state. + +### 05 Presentational Components + +Breaking the list component into two: list and row compomenent, member row +entity passed via props. + +### 06 Handling asynchronous calls + +Members fake api replaced with async call to api github to retrieve list of +members of a given team. + +### 07 Forms + +In this sample we will add a link in the members page that will navigate to a +"new member page". This new page will display a form where you have to enter +the avatar url, login and id of a new member (just supossing we can edit that info). + +### 08 ParamNavigation + Validations + +Edit a given member, here we learn how to add params to a navigation link and +how to obtain them from a component. + +Validation performed so far: + +- Login: required, must be a string (at least length 3). + +### 09 Redux + +Added Redux support, isolated state into Redux reducers, implement load, save, +basic validation cycle. This sample uses the fake api, in following samples +we will call async operations and fitting them into Redux architecture. + +### 10 SpinnerAsync + +Display a busy indicator when an ajax request is in progress. + +To have a global count of promises gong on we are using [react-promise-tracker](https://github.com/Lemoncode/react-promise-tracker) and to display a cool spinner [react-spinner](https://github.com/davidhu2000/react-spinners) + +### 11 Testing reducers + +Sample updated using Jest. + +### 12 Testing actions + +Sample updated using Jest. + +### 13 Testing components (Containers and Presentationals) + +Pending update Jest + Enzyme + +### 14 Replacing Redux Thunk with Redux Saga + +Pending update + +### 15 Lazy Loading and React-Router + +Pending update + +### 16 Add custom middlewares + +Pending update + +### 17 Add support for ReactHotloader and ReduxDev Tools. + +Pending update + +### 18 Hooks + +Replace class components by stateless components using Hooks. + +### 19 LoginForm + +Add a login page using Material-UI. + +# Contributors + +Special thanks to [Jehu Sagardoy](https://github.com/jsagardoy) for his contributions checking +and getting uptodate examples. + +# About Basefactor + Lemoncode + +We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. + +[Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. + +[Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. + +For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend From b2ef0bf343ab454142a1754229d6a15ee4bf0d81 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 11:22:49 +0200 Subject: [PATCH 02/37] ref: #187 Spanish translation --- readme_es.md | 95 +++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 49 deletions(-) diff --git a/readme_es.md b/readme_es.md index 92401985..573ae324 100644 --- a/readme_es.md +++ b/readme_es.md @@ -10,126 +10,123 @@ Ahora mismo hay dos carpetas principales: - [Hooks](./hooks): set de ejemplos migrados a hooks (ahora mismo 15 ejemplos), si eres nuevo en React, o vas a empezar a trabajar en un nuevo proyecto, Te recomendamos que lo hagas a través de ´estos ejemplos. -- [Old_class_components_samples](./old_class_components_samples): The old samples, just in case you need to work with older react - versions or you need to maintain legacy code. +- [Old_class_components_samples](./old_class_components_samples): Los ejemplos viejos, sólo en caso de que necesite trabajar en un proyecto de versiones viejas de React o necesites mantener código legacy. -If you want to make a deeper dive on React Hooks you can check this repo [React Hooks By Example](https://github.com/Lemoncode/react-hooks-by-example) +Si quieres sumerjirte más en React Hooks puedes chequear este repo: [React Hooks By Example](https://github.com/Lemoncode/react-hooks-by-example) Other guided repos available (react / redux + typescript): - [Redux By Sample](https://github.com/Lemoncode/redux-by-sample) -- [From React to Redux](https://github.com/Lemoncode/from-react-to-redux-ts) +- [Desde React a Redux](https://github.com/Lemoncode/from-react-to-redux-ts) - [Redux Sagas](https://github.com/Lemoncode/redux-sagas-typescript-by-example) -# Examples +# Ejemplos -The goal of this project is to provide a set of simple samples, providing and step by step guide to -start working with React and Typescript. Characteristics: +Características: -- Bundling based on webpack. -- React + Typescript based. -- Simple navigation using react-router. -- Managing async calls and updates. -- Using Redux library (not available yet on hooks version, coming soon). -- Handling async calls via Redux-Thunk + Redux Saga (not available yet on hooks version, coming soon) -- Adding unit testing support (not available yet on hooks version, coming soon). -- Implementing Lazy Loading (not available yet on hooks version, coming soon). +- Bundling basado en webpack. +- Basado en React + Typescript. +- Navegación simple usando react-router. +- Gestionando llamadas asíncronas y actualizaciones. +- Usando la librería Redux (todavía no está disponible para la version en Hooks, próximamente). +- Manejando llamadas asíncronas vía Redux-Thunk + Redux Saga (todavía no está disponible para la version en Hooks, próximamente). +- Añadiendo sporte para test unitarios (todavía no está disponible para la version en Hooks, próximamente). +- Implementando Lazy Loading (todavía no está disponible para la version en Hooks, próximamente). - ... -## To get started: +## Para empezar: -1. Install [NodeJS](http://www.nodejs.org) -2. Download this repo -3. Open the command line of your choice and cd to a sample directory within this repo on your machine -4. `npm install` - Installs packages -5. `npm start` - Builds the project and launch a lite web server (webpack-dev-server). -6. Navigate to [http://localhost:8080/](http://localhost:8080/) if your browser doesn't open automatically. +1. Instalar [NodeJS](http://www.nodejs.org) +2. Descarga este repo +3. Abre la consola de comandos que prefieras y haz 'cd' en el directorio de ejemplo dentro de este repo en tu máquina. +4. `npm install` - Instalación de los paquetes +5. `npm start` - Build del proyecto y lanza el servidor web (webpack-dev-server). +6. Copia y pega esta dirección en tu navegador [http://localhost:8080/](http://localhost:8080/) si ´éste no se abre automáticamente. -# samples +# muestras ## Hooks ### [00 Boiler plate](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/00_BoilerPlate) -Bundling + npm start based on webpack. +Bundling + npm start basado en webpack. ### [01 Hello React](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/01_HelloReact) -Display the text 'Hello React'. +Muestra el texto 'Hello React'. -Hello world, simples react render sample. +Hello world, muestra siemple de React render. ### [02 Properties](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/02_Properties) -Display the text 'Hello {name}' (where name is a prop -that contains a given name). +Muestra el texto 'Hello {name}' (donde nombre es una propiedad que contiene el nombre). -Introduce a basic React concept, handling properties. +Introducción al concepto básico de React, manejando propiedades. ### [03 State](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/03_State) -Starting from sample 02, let's the user change the name to be displayed. +Empezando desde la muestra 02, permite que el usuario cambie el nombre que se muestra. -Introduce a basic React concept, handling State using hooks. +Introducción al concepto básico de React, manejando el Estado (State) usando Hooks. ### [04 Callback](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/04_Callback) -Starting from sample 03, let the user change the name only +Empezando desde la nuestra 03, permite que el usario cambie la propiedad name solo cuando presiona sobre el botón _change_ . when he hits a _change_ button. -Using callbacks. +Usando callbacks. ### [05 Refactor](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/05_Refactor) -Refactor sample 04, cleanup and discussion on where to place the state. +Refactor de la muestra 04, Limpieza y discusión sobre dónde debe estar el estado. -Refactor the job done. +Reafactorizar el trabajo realizado. ### [06 Enable](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/06_Enable) -Starting from sample 05, enable / disable the _change_ button -when the text is empty or same name as original name,. +Empezando desde la nuestra 05, enable / disable del botón _change_ +cuando el texto está vacío o tiene el mismo nombre que originalmente,. -Enable/disable components. +Componentes Enable/disable ### [07 ColorPicker](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/07_ColorPicker) -Simple color picker demo (show how properties work). +demo simple de color picker (muestras cómo funcionan las propiedades). ### [08 ColorPicker Refactor](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/08_ColorPickerRefactor) -ColorPicker refactor. +ColorPicker refactorizado. ### [09 Sidebar](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/09_Sidebar) -Implementation of a single sidebar. +Simple implementación de un menú lateral. ### [10 Table Mock](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/10_TableMock) -Render a table and use a child component to render each row, using mock data. +Renderiza una tabla y usa un componente hijo para renderizar cada fila, usando un mock de datos. ### [11 Table Axios](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/11_TableAxios) -Starting from sample 10, remove mock data, hit a real REST API (Github api), use -axios to perform the fetch call. +Empezando desde la nuestra 10, elimina el mock de datos, utiliza una REST API real (api Github), utiliza axios para mejorar el rendimiento de la llamada fetch. ### [12 React Router](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/12_ReactRouter) -Starting from sample 03,start using React-Router (SPA navigation). +Empezando desde la nuestra 03, empezando a utilizar React-Router (navegación SPA). ### [13 Login Form](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) -Starting from sample 12, implement a basic login page, that will redirect the user to another page whenever the login has completed successfully. +Empezando desde la nuestra 12, implementa una página de login básica, que redireccione al usuario a otra página cuando el login haya completado satisfactoriamente. ### [14 Form Validation](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) -Starting from sample 13, add validation support to login form. +Empezando desde la nuestra 13, añadir validaciones al formulario de login. ### [15 Context](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/15_Context) -Starting from sample 14, learn how React 16 context api works. +SEmpezando desde la nuestra 14, learn how React 16 context api works. +SEmpezando desde la nuestra 14, emprender cómo funciona la API de React 16 Context. -## Old Class folder +## Carpeta class vieja ### 00 Boiler plate From 4393d3bdd380733cb9e4e5934bc1174e5f216539 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 12:06:35 +0200 Subject: [PATCH 03/37] ref: #187 Spanish translations and links to readme files --- readme.md | 4 +++- readme_es.md | 49 ++++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/readme.md b/readme.md index 26e45432..62ff986a 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,7 @@ # React Typescript by sample +[🇪🇸 Versión Español](./readme_es.md) + The goal of this project is to provide a set of simple samples, providing and step by step guide to start working with React and TypeScript. @@ -161,7 +163,7 @@ entity passed via props. ### 06 Handling asynchronous calls Members fake api replaced with async call to api github to retrieve list of -members of a given team. +members of a given organization. ### 07 Forms diff --git a/readme_es.md b/readme_es.md index 573ae324..413f504a 100644 --- a/readme_es.md +++ b/readme_es.md @@ -1,5 +1,7 @@ # React Typescript - ejemplos +[🇬🇧 English version](./readme.md) + El objetivo de este proyecto es ofrecer un set de ejemplos simples, proporcionando una guía paso a paso para empezar a trabajar con React y TypeScript. @@ -71,8 +73,8 @@ Introducción al concepto básico de React, manejando el Estado (State) usando H ### [04 Callback](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/04_Callback) -Empezando desde la nuestra 03, permite que el usario cambie la propiedad name solo cuando presiona sobre el botón _change_ . -when he hits a _change_ button. +Empezando desde la nuestra 03, permite que el usario cambie la propiedad name +solo cuando presiona sobre el botón _change_ . Usando callbacks. @@ -107,7 +109,8 @@ Renderiza una tabla y usa un componente hijo para renderizar cada fila, usando u ### [11 Table Axios](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/11_TableAxios) -Empezando desde la nuestra 10, elimina el mock de datos, utiliza una REST API real (api Github), utiliza axios para mejorar el rendimiento de la llamada fetch. +Empezando desde la nuestra 10, elimina el mock de datos, utiliza una REST API real (api Github), +utiliza axios para mejorar el rendimiento de la llamada fetch. ### [12 React Router](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/12_ReactRouter) @@ -115,7 +118,8 @@ Empezando desde la nuestra 03, empezando a utilizar React-Router (navegación SP ### [13 Login Form](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) -Empezando desde la nuestra 12, implementa una página de login básica, que redireccione al usuario a otra página cuando el login haya completado satisfactoriamente. +Empezando desde la nuestra 12, implementa una página de login básica, +que redireccione al usuario a otra página cuando el login haya completado satisfactoriamente. ### [14 Form Validation](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) @@ -130,49 +134,48 @@ SEmpezando desde la nuestra 14, emprender cómo funciona la API de React 16 Cont ### 00 Boiler plate -Bundling + npm start based on webpack. +Bundling + npm start basado en webpack. ### 01 Hello React -Hello world, simples react render sample. +Hello world, muestra siemple de React render. ### 02 Components -Creating a common header and about page react components. +Creando una cabecera común y una página 'about' con componentes de React. ### 03 Navigation -Creating a "members" page, adding navigation using react-router. +Creando una página de "miembros", añadir navegación usando react-router. ### 04 Display data -Create a read only list component (table >> tr >> td), reading list of members -from a fake api and dumping it into component state. +Crear un componenente de lista de 'sólo lectura' (table >> tr >> td), +leer una lista de miembros desde una API falsa y añadirlos dentro del componente 'state' ### 05 Presentational Components -Breaking the list component into two: list and row compomenent, member row -entity passed via props. +Dividir el componente de lista en dos: componente de Lista y Fila, +pasar la entidad del miembro a través de las 'props' del componente. ### 06 Handling asynchronous calls -Members fake api replaced with async call to api github to retrieve list of -members of a given team. +Reemplazar la API false con una llamada asíncrona a la API de github y obtener la lista de miembros de una organización. ### 07 Forms -In this sample we will add a link in the members page that will navigate to a -"new member page". This new page will display a form where you have to enter -the avatar url, login and id of a new member (just supossing we can edit that info). +En esta muestra añadiremos un link en la página de miembros que navegará hacia la 'página del miembro'. +Esta nueva página mostrará un formulario donde tendrás que introducir la url del avatar, el 'login' y el 'id' +del nuevo miembro (sólo suponiendo que podemos añadir esa info). ### 08 ParamNavigation + Validations -Edit a given member, here we learn how to add params to a navigation link and -how to obtain them from a component. +Editar un miembro seleccionado, aquí aprenderemos cómo añadir parámetros al link de navegación +y cómo obtenerlo desde el componente. -Validation performed so far: +La validación realizada hasta ahora: -- Login: required, must be a string (at least length 3). +- Login: requerido, debe ser una cadena de texto (al menos 3 caracteres de longitud). ### 09 Redux @@ -180,6 +183,10 @@ Added Redux support, isolated state into Redux reducers, implement load, save, basic validation cycle. This sample uses the fake api, in following samples we will call async operations and fitting them into Redux architecture. +Añadido soporte para Redux, estado aislado en 'Redux reducers', implementa carga, guardar, +ciclo de validación simple. Esta muestra usa una API falsa, en las siguientes muentras +haremos llamadas a operaciones asíncronas y las ajustaremos dentro de la arquitectura de Redux. + ### 10 SpinnerAsync Display a busy indicator when an ajax request is in progress. From 3a3c67b60486e43d46e01998e8c7b0bb3772b401 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 12:08:10 +0200 Subject: [PATCH 04/37] ref: #187 Spanish translations --- readme_es.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/readme_es.md b/readme_es.md index 413f504a..46855edd 100644 --- a/readme_es.md +++ b/readme_es.md @@ -179,10 +179,6 @@ La validación realizada hasta ahora: ### 09 Redux -Added Redux support, isolated state into Redux reducers, implement load, save, -basic validation cycle. This sample uses the fake api, in following samples -we will call async operations and fitting them into Redux architecture. - Añadido soporte para Redux, estado aislado en 'Redux reducers', implementa carga, guardar, ciclo de validación simple. Esta muestra usa una API falsa, en las siguientes muentras haremos llamadas a operaciones asíncronas y las ajustaremos dentro de la arquitectura de Redux. From a53071240b6c73602f692e9ad3fd3ac7d3ae8058 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 12:31:56 +0200 Subject: [PATCH 05/37] ref: #187 Spanish translations --- readme.md | 6 ++-- readme_es.md | 79 ++++++++++++++++++++++++++-------------------------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/readme.md b/readme.md index 62ff986a..b53b7d93 100644 --- a/readme.md +++ b/readme.md @@ -188,9 +188,11 @@ we will call async operations and fitting them into Redux architecture. ### 10 SpinnerAsync -Display a busy indicator when an ajax request is in progress. +Display a busy indicator while an ajax request is in progress. -To have a global count of promises gong on we are using [react-promise-tracker](https://github.com/Lemoncode/react-promise-tracker) and to display a cool spinner [react-spinner](https://github.com/davidhu2000/react-spinners) +To have a global count of promises gong on we are using +[react-promise-tracker](https://github.com/Lemoncode/react-promise-tracker) +and to display a cool spinner [react-spinner](https://github.com/davidhu2000/react-spinners) ### 11 Testing reducers diff --git a/readme_es.md b/readme_es.md index 46855edd..62d02455 100644 --- a/readme_es.md +++ b/readme_es.md @@ -59,7 +59,7 @@ Muestra el texto 'Hello React'. Hello world, muestra siemple de React render. -### [02 Properties](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/02_Properties) +### [02 Propiedades](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/02_Properties) Muestra el texto 'Hello {name}' (donde nombre es una propiedad que contiene el nombre). @@ -99,15 +99,15 @@ demo simple de color picker (muestras cómo funcionan las propiedades). ColorPicker refactorizado. -### [09 Sidebar](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/09_Sidebar) +### [09 menú lateral](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/09_Sidebar) Simple implementación de un menú lateral. -### [10 Table Mock](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/10_TableMock) +### [10 Tabla Mock](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/10_TableMock) Renderiza una tabla y usa un componente hijo para renderizar cada fila, usando un mock de datos. -### [11 Table Axios](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/11_TableAxios) +### [11 Tabla Axios](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/11_TableAxios) Empezando desde la nuestra 10, elimina el mock de datos, utiliza una REST API real (api Github), utiliza axios para mejorar el rendimiento de la llamada fetch. @@ -116,12 +116,12 @@ utiliza axios para mejorar el rendimiento de la llamada fetch. Empezando desde la nuestra 03, empezando a utilizar React-Router (navegación SPA). -### [13 Login Form](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) +### [13 Formulario Login](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/13_LoginForm) Empezando desde la nuestra 12, implementa una página de login básica, que redireccione al usuario a otra página cuando el login haya completado satisfactoriamente. -### [14 Form Validation](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) +### [14 Validación de formulario](https://github.com/Lemoncode/react-typescript-samples/tree/master/hooks/14_FormValidation) Empezando desde la nuestra 13, añadir validaciones al formulario de login. @@ -140,35 +140,35 @@ Bundling + npm start basado en webpack. Hello world, muestra siemple de React render. -### 02 Components +### 02 Componentes Creando una cabecera común y una página 'about' con componentes de React. -### 03 Navigation +### 03 Navegación Creando una página de "miembros", añadir navegación usando react-router. -### 04 Display data +### 04 Motrar datos Crear un componenente de lista de 'sólo lectura' (table >> tr >> td), leer una lista de miembros desde una API falsa y añadirlos dentro del componente 'state' -### 05 Presentational Components +### 05 Prensentación de componentes Dividir el componente de lista en dos: componente de Lista y Fila, pasar la entidad del miembro a través de las 'props' del componente. -### 06 Handling asynchronous calls +### 06 Manejando llamadas asíncronas Reemplazar la API false con una llamada asíncrona a la API de github y obtener la lista de miembros de una organización. -### 07 Forms +### 07 Formularios En esta muestra añadiremos un link en la página de miembros que navegará hacia la 'página del miembro'. Esta nueva página mostrará un formulario donde tendrás que introducir la url del avatar, el 'login' y el 'id' del nuevo miembro (sólo suponiendo que podemos añadir esa info). -### 08 ParamNavigation + Validations +### 08 Parámetros de navegación + Validaciones Editar un miembro seleccionado, aquí aprenderemos cómo añadir parámetros al link de navegación y cómo obtenerlo desde el componente. @@ -185,57 +185,58 @@ haremos llamadas a operaciones asíncronas y las ajustaremos dentro de la arquit ### 10 SpinnerAsync -Display a busy indicator when an ajax request is in progress. +Muestra un indicador de carga mientras la petición ajax está en progreso. -To have a global count of promises gong on we are using [react-promise-tracker](https://github.com/Lemoncode/react-promise-tracker) and to display a cool spinner [react-spinner](https://github.com/davidhu2000/react-spinners) +Para tener un recuento global de las promesas que estamos usando +[react-promise-tracker](https://github.com/Lemoncode/react-promise-tracker) +y mostras un bonito spinner [react-spinner](https://github.com/davidhu2000/react-spinners) -### 11 Testing reducers +### 11 Testeando reducers -Sample updated using Jest. +Muestra actualizada usando Jest. -### 12 Testing actions +### 12 Testeando acciones -Sample updated using Jest. +Muestra actualizada usando Jest. -### 13 Testing components (Containers and Presentationals) +### 13 Testeando componentes (Contenedores y presentaciones) -Pending update Jest + Enzyme +Pendiente de actualizar Jest + Enzyme -### 14 Replacing Redux Thunk with Redux Saga +### 14 Reemplazando Redux Thunk con Redux Saga -Pending update +Pendiente de actualizar -### 15 Lazy Loading and React-Router +### 15 Lazy Loading y React-Router -Pending update +Pendiente de actualizar -### 16 Add custom middlewares +### 16 Añadir middlewares personalizados -Pending update +Pendiente de actualizar -### 17 Add support for ReactHotloader and ReduxDev Tools. +### 17 Añadir soporte para ReactHotloader y herramientas ReduxDev -Pending update +Pendiente de actualizar ### 18 Hooks Replace class components by stateless components using Hooks. -### 19 LoginForm +### 19 Formulario Login -Add a login page using Material-UI. +Añadir página de Login usando AMaterial-UI. -# Contributors +# Colaboradores -Special thanks to [Jehu Sagardoy](https://github.com/jsagardoy) for his contributions checking -and getting uptodate examples. +Gracias, en especial a [Jehu Sagardoy](https://github.com/jsagardoy) por su colaboración, revisión y actualizaciones de los ejemplos. -# About Basefactor + Lemoncode +# Sobre Basefactor + Lemoncode -We are an innovating team of Javascript experts, passionate about turning your ideas into robust products. +Somos un equipo innovador de expertos en JavaScript, apasionados en convertir tus ideas en productos robustos y consistentes. -[Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services. +[Basefactor, consultoría por Lemoncode](http://www.basefactor.com) proporciona servicios de consultoría y servicios de orientación. -[Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. +[Lemoncode](http://lemoncode.net/services/en/#en-home) proporciona servicios de formación. -For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend +Para la audiencia de LATAM/España estamos llevando a cabo un Master Online Front End, más info: [http://lemoncode.net/master-frontend](http://lemoncode.net/master-frontend) From 942d642e0f036f0e5ededf4263fe96565d0e59e5 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 13:02:42 +0200 Subject: [PATCH 06/37] ref: #187 Spanish translations --- readme_es.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme_es.md b/readme_es.md index 62d02455..5df6c0e1 100644 --- a/readme_es.md +++ b/readme_es.md @@ -16,7 +16,7 @@ un nuevo proyecto, Te recomendamos que lo hagas a través de ´estos ejemplos. Si quieres sumerjirte más en React Hooks puedes chequear este repo: [React Hooks By Example](https://github.com/Lemoncode/react-hooks-by-example) -Other guided repos available (react / redux + typescript): +Otros repos guiados disponibles (React / Redux + TypeScript): - [Redux By Sample](https://github.com/Lemoncode/redux-by-sample) - [Desde React a Redux](https://github.com/Lemoncode/from-react-to-redux-ts) From 70d927e35cd11671352473b7ea9907288b6d4e12 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 15:57:09 +0200 Subject: [PATCH 07/37] ref: #187 Spanish translations --- readme.md | 3 ++- readme_es.md | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index b53b7d93..7f214748 100644 --- a/readme.md +++ b/readme.md @@ -243,4 +243,5 @@ We are an innovating team of Javascript experts, passionate about turning your i [Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services. -For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend +For the LATAM/Spanish audience we are running an Online Front End Master degree, +more info: [http://lemoncode.net/master-frontend](http://lemoncode.net/master-frontend) diff --git a/readme_es.md b/readme_es.md index 5df6c0e1..0940ba3a 100644 --- a/readme_es.md +++ b/readme_es.md @@ -36,7 +36,7 @@ Características: - Implementando Lazy Loading (todavía no está disponible para la version en Hooks, próximamente). - ... -## Para empezar: +## Para empezar 1. Instalar [NodeJS](http://www.nodejs.org) 2. Descarga este repo @@ -239,4 +239,5 @@ Somos un equipo innovador de expertos en JavaScript, apasionados en convertir tu [Lemoncode](http://lemoncode.net/services/en/#en-home) proporciona servicios de formación. -Para la audiencia de LATAM/España estamos llevando a cabo un Master Online Front End, más info: [http://lemoncode.net/master-frontend](http://lemoncode.net/master-frontend) +Para la audiencia de LATAM/España estamos llevando a cabo un Master Online Front End, más info: +[http://lemoncode.net/master-frontend](http://lemoncode.net/master-frontend) From 333e5d7e4712b4bf35fc48a91b416d685589cf4c Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 16:18:47 +0200 Subject: [PATCH 08/37] ref: #187 update 00 package.json --- hooks/00_BoilerPlate/package.json | 33 +++++++++++++------------- hooks/00_BoilerPlate/webpack.config.js | 29 +++++++++++----------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/hooks/00_BoilerPlate/package.json b/hooks/00_BoilerPlate/package.json index a259e937..fa5fa952 100644 --- a/hooks/00_BoilerPlate/package.json +++ b/hooks/00_BoilerPlate/package.json @@ -10,26 +10,27 @@ "keywords": [ "react", "typescript", - "hooks" + "hooks", + "lemoncode" ], "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" } } diff --git a/hooks/00_BoilerPlate/webpack.config.js b/hooks/00_BoilerPlate/webpack.config.js index bf1cad6c..08e2685c 100644 --- a/hooks/00_BoilerPlate/webpack.config.js +++ b/hooks/00_BoilerPlate/webpack.config.js @@ -8,12 +8,12 @@ var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./main.ts"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From ecf553d4fef748e78f1b59e9f559008a087d8037 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 17:02:36 +0200 Subject: [PATCH 09/37] ref: #187 update 01 package.json --- hooks/01_HelloReact/package.json | 38 +++++++++++++-------------- hooks/01_HelloReact/webpack.config.js | 29 ++++++++++---------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/hooks/01_HelloReact/package.json b/hooks/01_HelloReact/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/01_HelloReact/package.json +++ b/hooks/01_HelloReact/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/01_HelloReact/webpack.config.js b/hooks/01_HelloReact/webpack.config.js index 31ab3dba..e4f92b3e 100644 --- a/hooks/01_HelloReact/webpack.config.js +++ b/hooks/01_HelloReact/webpack.config.js @@ -8,12 +8,12 @@ var basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From cca0948b99cff770a24c8e20081d740cd580fb21 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 17:03:01 +0200 Subject: [PATCH 10/37] ref: #187 update 00 package.json --- hooks/00_BoilerPlate/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hooks/00_BoilerPlate/package.json b/hooks/00_BoilerPlate/package.json index fa5fa952..12b2f5b2 100644 --- a/hooks/00_BoilerPlate/package.json +++ b/hooks/00_BoilerPlate/package.json @@ -10,8 +10,7 @@ "keywords": [ "react", "typescript", - "hooks", - "lemoncode" + "hooks" ], "author": "Braulio Diez Botella", "license": "MIT", From d38144d14eb55945b78299fdaaf6b27f3fc2d491 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 23:10:49 +0200 Subject: [PATCH 11/37] ref: #187 update 01,02 package.json --- hooks/00_BoilerPlate/webpack.config.js | 10 +++---- hooks/01_HelloReact/webpack.config.js | 10 +++---- hooks/02_Properties/package.json | 38 ++++++++++++------------- hooks/02_Properties/webpack.config.js | 39 +++++++++++++------------- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/hooks/00_BoilerPlate/webpack.config.js b/hooks/00_BoilerPlate/webpack.config.js index 08e2685c..37715722 100644 --- a/hooks/00_BoilerPlate/webpack.config.js +++ b/hooks/00_BoilerPlate/webpack.config.js @@ -1,9 +1,9 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), diff --git a/hooks/01_HelloReact/webpack.config.js b/hooks/01_HelloReact/webpack.config.js index e4f92b3e..32eff849 100644 --- a/hooks/01_HelloReact/webpack.config.js +++ b/hooks/01_HelloReact/webpack.config.js @@ -1,9 +1,9 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), diff --git a/hooks/02_Properties/package.json b/hooks/02_Properties/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/02_Properties/package.json +++ b/hooks/02_Properties/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/02_Properties/webpack.config.js b/hooks/02_Properties/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/02_Properties/webpack.config.js +++ b/hooks/02_Properties/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From 5aca3e49691aefe2e65df146fa061aa51c1209b0 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Mon, 20 Jul 2020 23:17:28 +0200 Subject: [PATCH 12/37] ref: #187 update 03,04 package.json --- hooks/03_State/package.json | 38 ++++++++++++++-------------- hooks/03_State/webpack.config.js | 39 +++++++++++++++-------------- hooks/04_Callback/package.json | 38 ++++++++++++++-------------- hooks/04_Callback/webpack.config.js | 39 +++++++++++++++-------------- 4 files changed, 78 insertions(+), 76 deletions(-) diff --git a/hooks/03_State/package.json b/hooks/03_State/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/03_State/package.json +++ b/hooks/03_State/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/03_State/webpack.config.js b/hooks/03_State/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/03_State/webpack.config.js +++ b/hooks/03_State/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/04_Callback/package.json b/hooks/04_Callback/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/04_Callback/package.json +++ b/hooks/04_Callback/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/04_Callback/webpack.config.js b/hooks/04_Callback/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/04_Callback/webpack.config.js +++ b/hooks/04_Callback/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From 84ba4e55eb18c0344bf3dbf4a1fad1c6827f687d Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 09:57:23 +0200 Subject: [PATCH 13/37] ref: #187 update 05 - 09 and translations --- hooks/05_Refactor/package.json | 38 +++++++------- hooks/05_Refactor/webpack.config.js | 39 ++++++++------- hooks/06_Enable/package.json | 38 +++++++------- hooks/06_Enable/webpack.config.js | 39 ++++++++------- hooks/07_ColorPicker/package.json | 38 +++++++------- hooks/07_ColorPicker/webpack.config.js | 39 ++++++++------- hooks/08_ColorPickerRefactor/package.json | 38 +++++++------- .../08_ColorPickerRefactor/webpack.config.js | 39 ++++++++------- hooks/09_Sidebar/package.json | 40 +++++++-------- hooks/09_Sidebar/webpack.config.js | 50 +++++++++---------- 10 files changed, 199 insertions(+), 199 deletions(-) diff --git a/hooks/05_Refactor/package.json b/hooks/05_Refactor/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/05_Refactor/package.json +++ b/hooks/05_Refactor/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/05_Refactor/webpack.config.js b/hooks/05_Refactor/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/05_Refactor/webpack.config.js +++ b/hooks/05_Refactor/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/06_Enable/package.json b/hooks/06_Enable/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/06_Enable/package.json +++ b/hooks/06_Enable/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/06_Enable/webpack.config.js b/hooks/06_Enable/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/06_Enable/webpack.config.js +++ b/hooks/06_Enable/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/07_ColorPicker/package.json b/hooks/07_ColorPicker/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/07_ColorPicker/package.json +++ b/hooks/07_ColorPicker/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/07_ColorPicker/webpack.config.js b/hooks/07_ColorPicker/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/07_ColorPicker/webpack.config.js +++ b/hooks/07_ColorPicker/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/08_ColorPickerRefactor/package.json b/hooks/08_ColorPickerRefactor/package.json index bfa0e4eb..264e71d2 100644 --- a/hooks/08_ColorPickerRefactor/package.json +++ b/hooks/08_ColorPickerRefactor/package.json @@ -15,27 +15,27 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/08_ColorPickerRefactor/webpack.config.js b/hooks/08_ColorPickerRefactor/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/08_ColorPickerRefactor/webpack.config.js +++ b/hooks/08_ColorPickerRefactor/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/09_Sidebar/package.json b/hooks/09_Sidebar/package.json index eadce68d..40171b2f 100644 --- a/hooks/09_Sidebar/package.json +++ b/hooks/09_Sidebar/package.json @@ -15,28 +15,28 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/node": "^11.9.4", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index eebdc585..7420e37f 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"] + extensions: [".js", ".ts", ".tsx", ".css"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,13 +31,8 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } - }, - { - test: /\.css$/, - include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, @@ -49,30 +44,31 @@ module.exports = { options: { modules: true, localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true - } - } - ] + camelCase: true, + }, + }, + ], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From 121ac7c9e4a726dd7b6c5dbae68ed254f1f9fa68 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 10:01:55 +0200 Subject: [PATCH 14/37] ref: #187 update 09, 10 and translations --- hooks/09_Sidebar/webpack.config.js | 5 ++++ hooks/10_TableMock/package.json | 40 ++++++++++++------------- hooks/10_TableMock/webpack.config.js | 45 ++++++++++++++-------------- readme.md | 5 ++-- readme_es.md | 4 ++- 5 files changed, 54 insertions(+), 45 deletions(-) diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index 7420e37f..750f00af 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -34,6 +34,11 @@ module.exports = { babelCore: "@babel/core", // needed for Babel v7 }, }, + { + test: /\.css$/, + include: /node_modules/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, { test: /\.css$/, exclude: /node_modules/, diff --git a/hooks/10_TableMock/package.json b/hooks/10_TableMock/package.json index eadce68d..40171b2f 100644 --- a/hooks/10_TableMock/package.json +++ b/hooks/10_TableMock/package.json @@ -15,28 +15,28 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/node": "^11.9.4", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2" + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/10_TableMock/webpack.config.js b/hooks/10_TableMock/webpack.config.js index eebdc585..750f00af 100644 --- a/hooks/10_TableMock/webpack.config.js +++ b/hooks/10_TableMock/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"] + extensions: [".js", ".ts", ".tsx", ".css"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,8 +31,8 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, @@ -49,30 +49,31 @@ module.exports = { options: { modules: true, localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true - } - } - ] + camelCase: true, + }, + }, + ], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/readme.md b/readme.md index 7f214748..e728a6aa 100644 --- a/readme.md +++ b/readme.md @@ -232,8 +232,9 @@ Add a login page using Material-UI. # Contributors -Special thanks to [Jehu Sagardoy](https://github.com/jsagardoy) for his contributions checking -and getting uptodate examples. +Thank you very much to the contributors for keeping the project updated in all the examples. + +- [Jehu Sagardoy](https://github.com/jsagardoy) # About Basefactor + Lemoncode diff --git a/readme_es.md b/readme_es.md index 0940ba3a..baccb55e 100644 --- a/readme_es.md +++ b/readme_es.md @@ -229,7 +229,9 @@ Añadir página de Login usando AMaterial-UI. # Colaboradores -Gracias, en especial a [Jehu Sagardoy](https://github.com/jsagardoy) por su colaboración, revisión y actualizaciones de los ejemplos. +Muchas gracias a los colaborades por mantener el proyecto actualizado en todos los ejemplos. + +- [Jehu Sagardoy](https://github.com/jsagardoy) # Sobre Basefactor + Lemoncode From 034ec6a27d935261a478a8a2547d8dbd49979ae4 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 10:27:00 +0200 Subject: [PATCH 15/37] ref: #187 update 09, 11 webpack --- hooks/09_Sidebar/webpack.config.js | 5 --- hooks/11_TableAxios/.babelrc | 7 ++-- hooks/11_TableAxios/package.json | 46 +++++++++++++----------- hooks/11_TableAxios/webpack.config.js | 50 ++++++++++++--------------- 4 files changed, 53 insertions(+), 55 deletions(-) diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index 750f00af..7420e37f 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -34,11 +34,6 @@ module.exports = { babelCore: "@babel/core", // needed for Babel v7 }, }, - { - test: /\.css$/, - include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"] - }, { test: /\.css$/, exclude: /node_modules/, diff --git a/hooks/11_TableAxios/.babelrc b/hooks/11_TableAxios/.babelrc index 957cae3e..06770f7d 100644 --- a/hooks/11_TableAxios/.babelrc +++ b/hooks/11_TableAxios/.babelrc @@ -5,6 +5,9 @@ { "useBuiltIns": "entry" } - ] - ] + ], + "@babel/preset-typescript", + "@babel/preset-react" + ], + "plugins": ["@babel/plugin-transform-runtime"] } diff --git a/hooks/11_TableAxios/package.json b/hooks/11_TableAxios/package.json index 7ef95a14..0d0d92b0 100644 --- a/hooks/11_TableAxios/package.json +++ b/hooks/11_TableAxios/package.json @@ -15,29 +15,33 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/node": "^11.9.4", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/plugin-transform-runtime": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "axios": "^0.18.0", - "react": "^16.8.2", - "react-dom": "^16.8.2" + "@babel/runtime": "^7.10.5", + "axios": "^0.19.2", + "react": "^16.13.1", + "react-dom": "^16.13.1" } } diff --git a/hooks/11_TableAxios/webpack.config.js b/hooks/11_TableAxios/webpack.config.js index eebdc585..7420e37f 100644 --- a/hooks/11_TableAxios/webpack.config.js +++ b/hooks/11_TableAxios/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx", ".css"] + extensions: [".js", ".ts", ".tsx", ".css"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,13 +31,8 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } - }, - { - test: /\.css$/, - include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, @@ -49,30 +44,31 @@ module.exports = { options: { modules: true, localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true - } - } - ] + camelCase: true, + }, + }, + ], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From bb21e6a01c69234175a72e04960a36a8b119b953 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 10:41:42 +0200 Subject: [PATCH 16/37] ref: #187 update 09 webpack --- hooks/09_Sidebar/webpack.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index 7420e37f..36373163 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -33,6 +33,11 @@ module.exports = { useBabel: true, babelCore: "@babel/core", // needed for Babel v7 }, + }, + { + test: /\.css$/, + include: /node_modules/, + use: [MiniCssExtractPlugin.loader, "css-loader"] }, { test: /\.css$/, From 7d45713f013c7ea337906027cd3f9ed89297cd5b Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 10:55:09 +0200 Subject: [PATCH 17/37] ref: #187 update 09 webpack --- hooks/09_Sidebar/webpack.config.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index 36373163..c4980707 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -33,11 +33,11 @@ module.exports = { useBabel: true, babelCore: "@babel/core", // needed for Babel v7 }, - }, - { - test: /\.css$/, - include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + { + test: /\.css$/, + include: /node_modules/, + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.css$/, From cd511060208fed4efef255fb6acb7d7661b91d1a Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 11:38:08 +0200 Subject: [PATCH 18/37] ref: #187 update 09 pending update readme --- hooks/09_Sidebar/webpack.config.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hooks/09_Sidebar/webpack.config.js b/hooks/09_Sidebar/webpack.config.js index c4980707..c9996585 100644 --- a/hooks/09_Sidebar/webpack.config.js +++ b/hooks/09_Sidebar/webpack.config.js @@ -47,9 +47,10 @@ module.exports = { { loader: "css-loader", options: { - modules: true, - localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true, + modules: { + localIdentName: "[name]__[local]___[hash:base64:5]", + }, + localsConvention: "camelCase", }, }, ], From c4fdd2cd1dc15b35a33160426f6bc96a203f1aa4 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Tue, 21 Jul 2020 11:57:11 +0200 Subject: [PATCH 19/37] ref: #187 update 09 - 11 pending update readme async await --- hooks/09_Sidebar/Readme.md | 7 ++++--- hooks/10_TableMock/webpack.config.js | 9 +++++---- hooks/11_TableAxios/src/components/memberTable.tsx | 9 ++++----- hooks/11_TableAxios/webpack.config.js | 12 +++++++++--- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/hooks/09_Sidebar/Readme.md b/hooks/09_Sidebar/Readme.md index be7bddb2..e3dda427 100644 --- a/hooks/09_Sidebar/Readme.md +++ b/hooks/09_Sidebar/Readme.md @@ -89,9 +89,10 @@ _./webpack.config.js_ + { + loader: 'css-loader', + options: { -+ modules: true, -+ localIdentName: '[name]__[local]___[hash:base64:5]', -+ camelCase: true, ++ modules: { ++ localIdentName: "[name]__[local]___[hash:base64:5]", ++ }, ++ localsConvention: "camelCase", + }, + }, + ] diff --git a/hooks/10_TableMock/webpack.config.js b/hooks/10_TableMock/webpack.config.js index 750f00af..c9996585 100644 --- a/hooks/10_TableMock/webpack.config.js +++ b/hooks/10_TableMock/webpack.config.js @@ -37,7 +37,7 @@ module.exports = { { test: /\.css$/, include: /node_modules/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.css$/, @@ -47,9 +47,10 @@ module.exports = { { loader: "css-loader", options: { - modules: true, - localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true, + modules: { + localIdentName: "[name]__[local]___[hash:base64:5]", + }, + localsConvention: "camelCase", }, }, ], diff --git a/hooks/11_TableAxios/src/components/memberTable.tsx b/hooks/11_TableAxios/src/components/memberTable.tsx index eee44798..4ae64fa6 100644 --- a/hooks/11_TableAxios/src/components/memberTable.tsx +++ b/hooks/11_TableAxios/src/components/memberTable.tsx @@ -7,10 +7,9 @@ const useMemberCollection = () => { MemberEntity[] >([]); - const loadMemberCollection = () => { - getMembersCollection().then(memberCollection => - setMemberCollection(memberCollection) - ); + const loadMemberCollection = async () => { + const memberCollection = await getMembersCollection(); + setMemberCollection(memberCollection); }; return { memberCollection, loadMemberCollection }; @@ -34,7 +33,7 @@ export const MemberTableComponent = () => { - {memberCollection.map(member => ( + {memberCollection.map((member) => ( ))} diff --git a/hooks/11_TableAxios/webpack.config.js b/hooks/11_TableAxios/webpack.config.js index 7420e37f..c9996585 100644 --- a/hooks/11_TableAxios/webpack.config.js +++ b/hooks/11_TableAxios/webpack.config.js @@ -34,6 +34,11 @@ module.exports = { babelCore: "@babel/core", // needed for Babel v7 }, }, + { + test: /\.css$/, + include: /node_modules/, + use: [MiniCssExtractPlugin.loader, "css-loader"], + }, { test: /\.css$/, exclude: /node_modules/, @@ -42,9 +47,10 @@ module.exports = { { loader: "css-loader", options: { - modules: true, - localIdentName: "[name]__[local]___[hash:base64:5]", - camelCase: true, + modules: { + localIdentName: "[name]__[local]___[hash:base64:5]", + }, + localsConvention: "camelCase", }, }, ], From bde0b830e89a9f6abb5c81899d9d2a811ae59c16 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Wed, 22 Jul 2020 14:38:52 +0200 Subject: [PATCH 20/37] ref: #187 update 09 - 11 update readme async await --- hooks/11_TableAxios/Readme.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/hooks/11_TableAxios/Readme.md b/hooks/11_TableAxios/Readme.md index 4808c875..7a5332d0 100644 --- a/hooks/11_TableAxios/Readme.md +++ b/hooks/11_TableAxios/Readme.md @@ -67,6 +67,31 @@ export const getMembersCollection = (): Promise => { + })); ``` +- Adding async await calling member api + +To make the async await work, we should install +- `npm install -D @babel/plugin-transform-runtime` +- `npm install -P @babel/runtime` + +and add to the .babelrc + +_.babelrc_ +```bash + "plugins": ["@babel/plugin-transform-runtime"] +``` + +_./src/components/memberTable.tsx_ +```diff +- const loadMemberCollection = () => { +- getMembersCollection().then(memberCollection => +- setMemberCollection(memberCollection) +- ); + ++ const loadMemberCollection = async () => { ++ const memberCollection = await getMembersCollection(); ++ setMemberCollection(memberCollection); +``` + - Aaaand... we don't need to add any update on the rest of the application, why? The function is providing the same contract, it returns a promise, let's give a try: From 57d15cf1cf3f9adc926755defd6d14b0e7c13aee Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 24 Jul 2020 12:45:08 +0200 Subject: [PATCH 21/37] ref: #187 update 12, 13 refactor routes --- hooks/12_ReactRouter/.babelrc | 4 +- hooks/12_ReactRouter/package.json | 45 ++++++++++---------- hooks/12_ReactRouter/webpack.config.js | 39 ++++++++--------- hooks/13_LoginForm/package.json | 49 ++++++++++++---------- hooks/13_LoginForm/src/pages/loginPage.tsx | 11 +++-- hooks/13_LoginForm/webpack.config.js | 39 ++++++++--------- 6 files changed, 98 insertions(+), 89 deletions(-) diff --git a/hooks/12_ReactRouter/.babelrc b/hooks/12_ReactRouter/.babelrc index 957cae3e..d09d473e 100644 --- a/hooks/12_ReactRouter/.babelrc +++ b/hooks/12_ReactRouter/.babelrc @@ -5,6 +5,8 @@ { "useBuiltIns": "entry" } - ] + ], + "@babel/preset-typescript", + "@babel/preset-react" ] } diff --git a/hooks/12_ReactRouter/package.json b/hooks/12_ReactRouter/package.json index 2ff4e9af..fb377361 100644 --- a/hooks/12_ReactRouter/package.json +++ b/hooks/12_ReactRouter/package.json @@ -15,29 +15,32 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", - "@types/react-router-dom": "^4.3.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.5", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "react": "^16.8.2", - "react-dom": "^16.8.2", - "react-router-dom": "^4.3.1" + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0" } } diff --git a/hooks/12_ReactRouter/webpack.config.js b/hooks/12_ReactRouter/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/12_ReactRouter/webpack.config.js +++ b/hooks/12_ReactRouter/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; diff --git a/hooks/13_LoginForm/package.json b/hooks/13_LoginForm/package.json index d22ed28f..258ceb77 100644 --- a/hooks/13_LoginForm/package.json +++ b/hooks/13_LoginForm/package.json @@ -15,31 +15,34 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", - "@types/react-router-dom": "^4.3.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.5", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "@material-ui/core": "^4.0.1", - "@material-ui/icons": "^4.0.1", - "react": "^16.8.2", - "react-dom": "^16.8.2", - "react-router-dom": "^4.3.1" + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0" } } diff --git a/hooks/13_LoginForm/src/pages/loginPage.tsx b/hooks/13_LoginForm/src/pages/loginPage.tsx index 05e51a77..a6fbf0cf 100644 --- a/hooks/13_LoginForm/src/pages/loginPage.tsx +++ b/hooks/13_LoginForm/src/pages/loginPage.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { withRouter, RouteComponentProps } from "react-router-dom"; +import { useHistory } from "react-router-dom"; import makeStyles from "@material-ui/styles/makeStyles"; import createStyles from "@material-ui/styles/createStyles"; import Card from "@material-ui/core/Card"; @@ -21,18 +21,19 @@ const useStyles = makeStyles(theme => }) ); -interface Props extends RouteComponentProps {} +interface Props {}; -const LoginPageInner = (props: Props) => { +export const LoginPage = (props: Props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); + const history = useHistory(); const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); const classes = useStyles(); const onLogin = () => { if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); + history.push("/pageB"); } else { setShowLoginFailedMsg(true); } @@ -66,8 +67,6 @@ const LoginPageInner = (props: Props) => { ); }; -export const LoginPage = withRouter(LoginPageInner); - interface PropsForm { onLogin: () => void; onUpdateField: (name: string, value: any) => void; diff --git a/hooks/13_LoginForm/webpack.config.js b/hooks/13_LoginForm/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/13_LoginForm/webpack.config.js +++ b/hooks/13_LoginForm/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From c940328331550b1bbd42df09322821ffb2ba79e7 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 24 Jul 2020 13:37:25 +0200 Subject: [PATCH 22/37] ref: #187 update 14 form validation --- hooks/14_FormValidation/package.json | 49 ++++++++++--------- .../14_FormValidation/src/pages/loginPage.tsx | 11 ++--- hooks/14_FormValidation/webpack.config.js | 39 ++++++++------- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/hooks/14_FormValidation/package.json b/hooks/14_FormValidation/package.json index 2914eb69..1360a87c 100644 --- a/hooks/14_FormValidation/package.json +++ b/hooks/14_FormValidation/package.json @@ -15,32 +15,35 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", - "@types/react-router-dom": "^4.3.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.5", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "@material-ui/core": "^4.0.1", - "@material-ui/icons": "^4.0.1", + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", "lc-form-validation": "^2.0.0", - "react": "^16.8.2", - "react-dom": "^16.8.2", - "react-router-dom": "^4.3.1" + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0" } } diff --git a/hooks/14_FormValidation/src/pages/loginPage.tsx b/hooks/14_FormValidation/src/pages/loginPage.tsx index 5dce227a..09f017c3 100644 --- a/hooks/14_FormValidation/src/pages/loginPage.tsx +++ b/hooks/14_FormValidation/src/pages/loginPage.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { Link } from "react-router-dom"; -import { withRouter, RouteComponentProps } from "react-router-dom"; +import { useHistory } from "react-router-dom"; import makeStyles from "@material-ui/styles/makeStyles"; import createStyles from "@material-ui/styles/createStyles"; import Card from "@material-ui/core/Card"; @@ -29,9 +29,9 @@ const useStyles = makeStyles(theme => }) ); -interface Props extends RouteComponentProps {} +interface Props {} -const LoginPageInner = (props: Props) => { +export const LoginPage = (props: Props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); @@ -40,12 +40,13 @@ const LoginPageInner = (props: Props) => { ); const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); const classes = useStyles(); + const history = useHistory(); const onLogin = () => { loginFormValidation.validateForm(loginInfo).then(formValidationResult => { if (formValidationResult.succeeded) { if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); + history.push("/pageB"); } else { setShowLoginFailedMsg(true); } @@ -98,8 +99,6 @@ const LoginPageInner = (props: Props) => { ); }; -export const LoginPage = withRouter(LoginPageInner); - interface PropsForm { onLogin: () => void; onUpdateField: (string, any) => void; diff --git a/hooks/14_FormValidation/webpack.config.js b/hooks/14_FormValidation/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/14_FormValidation/webpack.config.js +++ b/hooks/14_FormValidation/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From 4bad05d34ddea5c97bcb8fe816cf84bb68ff830a Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 24 Jul 2020 13:40:36 +0200 Subject: [PATCH 23/37] ref: #187 update 15 context from 14 --- hooks/15_Context/package.json | 49 ++++++++++++++++-------------- hooks/15_Context/webpack.config.js | 39 ++++++++++++------------ 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/hooks/15_Context/package.json b/hooks/15_Context/package.json index 2914eb69..1360a87c 100644 --- a/hooks/15_Context/package.json +++ b/hooks/15_Context/package.json @@ -15,32 +15,35 @@ "author": "Braulio Diez Botella", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.2.3", - "@babel/core": "^7.2.2", - "@babel/polyfill": "^7.2.5", - "@babel/preset-env": "^7.3.1", - "@types/react": "^16.8.3", - "@types/react-dom": "^16.8.1", - "@types/react-router-dom": "^4.3.1", + "@babel/cli": "^7.10.5", + "@babel/core": "^7.10.5", + "@babel/polyfill": "^7.10.4", + "@babel/preset-env": "^7.10.4", + "@babel/preset-react": "^7.10.4", + "@babel/preset-typescript": "^7.10.4", + "@types/node": "^14.0.24", + "@types/react": "^16.9.43", + "@types/react-dom": "^16.9.8", + "@types/react-router-dom": "^5.1.5", "awesome-typescript-loader": "^5.2.1", - "babel-loader": "^8.0.5", - "css-loader": "^2.1.0", - "file-loader": "^3.0.1", - "html-webpack-plugin": "^3.2.0", - "mini-css-extract-plugin": "^0.5.0", - "style-loader": "^0.23.1", - "typescript": "^3.3.3", - "url-loader": "^1.1.2", - "webpack": "^4.29.3", - "webpack-cli": "^3.2.3", - "webpack-dev-server": "^3.1.14" + "babel-loader": "^8.1.0", + "css-loader": "^3.6.0", + "file-loader": "^6.0.0", + "html-webpack-plugin": "^4.3.0", + "mini-css-extract-plugin": "^0.9.0", + "style-loader": "^1.2.1", + "typescript": "^3.9.7", + "url-loader": "^4.1.0", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.11.0" }, "dependencies": { - "@material-ui/core": "^4.0.1", - "@material-ui/icons": "^4.0.1", + "@material-ui/core": "^4.11.0", + "@material-ui/icons": "^4.9.1", "lc-form-validation": "^2.0.0", - "react": "^16.8.2", - "react-dom": "^16.8.2", - "react-router-dom": "^4.3.1" + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router-dom": "^5.2.0" } } diff --git a/hooks/15_Context/webpack.config.js b/hooks/15_Context/webpack.config.js index 31ab3dba..32eff849 100644 --- a/hooks/15_Context/webpack.config.js +++ b/hooks/15_Context/webpack.config.js @@ -1,19 +1,19 @@ -var HtmlWebpackPlugin = require("html-webpack-plugin"); -var MiniCssExtractPlugin = require("mini-css-extract-plugin"); -var webpack = require("webpack"); -var path = require("path"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const webpack = require("webpack"); +const path = require("path"); -var basePath = __dirname; +const basePath = __dirname; module.exports = { context: path.join(basePath, "src"), resolve: { - extensions: [".js", ".ts", ".tsx"] + extensions: [".js", ".ts", ".tsx"], }, entry: ["@babel/polyfill", "./index.tsx"], output: { path: path.join(basePath, "dist"), - filename: "bundle.js" + filename: "bundle.js", }, devtool: "source-map", devServer: { @@ -21,7 +21,7 @@ module.exports = { inline: true, // Enable watch and live reload host: "localhost", port: 8080, - stats: "errors-only" + stats: "errors-only", }, module: { rules: [ @@ -31,32 +31,33 @@ module.exports = { loader: "awesome-typescript-loader", options: { useBabel: true, - babelCore: "@babel/core" // needed for Babel v7 - } + babelCore: "@babel/core", // needed for Babel v7 + }, }, { test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"] + use: [MiniCssExtractPlugin.loader, "css-loader"], }, { test: /\.(png|jpg|gif|svg)$/, loader: "file-loader", options: { - name: "assets/img/[name].[ext]?[hash]" - } - } - ] + name: "assets/img/[name].[ext]?[hash]", + esModule: false, + }, + }, + ], }, plugins: [ //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: "index.html", //Name of file in ./dist/ template: "index.html", //Name of template in ./src - hash: true + hash: true, }), new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" - }) - ] + chunkFilename: "[id].css", + }), + ], }; From 4b9952e5464a7688bbc197f683be72dd5fb6cb4e Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 24 Jul 2020 15:28:42 +0200 Subject: [PATCH 24/37] ref: #187 thanks delamux --- readme.md | 1 + readme_es.md | 1 + 2 files changed, 2 insertions(+) diff --git a/readme.md b/readme.md index e728a6aa..9036f076 100644 --- a/readme.md +++ b/readme.md @@ -235,6 +235,7 @@ Add a login page using Material-UI. Thank you very much to the contributors for keeping the project updated in all the examples. - [Jehu Sagardoy](https://github.com/jsagardoy) +- [Luis del Amo](https://github.com/delamux) # About Basefactor + Lemoncode diff --git a/readme_es.md b/readme_es.md index baccb55e..2107c97f 100644 --- a/readme_es.md +++ b/readme_es.md @@ -232,6 +232,7 @@ Añadir página de Login usando AMaterial-UI. Muchas gracias a los colaborades por mantener el proyecto actualizado en todos los ejemplos. - [Jehu Sagardoy](https://github.com/jsagardoy) +- [Luis del Amo](https://github.com/delamux) # Sobre Basefactor + Lemoncode From 70641258b9b83af6b97095c039e1b13a64a58941 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Sat, 25 Jul 2020 13:40:46 +0200 Subject: [PATCH 25/37] ref: #187 adding types --- hooks/02_Properties/src/hello.tsx | 6 +-- hooks/03_State/src/hello.tsx | 2 +- hooks/03_State/src/nameEdit.tsx | 2 +- hooks/04_Callback/src/hello.tsx | 2 +- hooks/04_Callback/src/nameEdit.tsx | 2 +- hooks/05_Refactor/src/hello.tsx | 2 +- hooks/05_Refactor/src/nameEdit.tsx | 2 +- hooks/06_Enable/src/hello.tsx | 2 +- hooks/06_Enable/src/nameEdit.tsx | 11 +++-- .../src/components/colorBrowser.tsx | 6 +-- .../src/components/colorPicker.tsx | 2 +- hooks/07_ColorPicker/src/components/hello.tsx | 2 +- .../src/components/nameEdit.tsx | 2 +- .../src/components/colorBrowser.tsx | 2 +- .../src/components/colorPicker.tsx | 8 ++-- .../src/components/hello.tsx | 2 +- .../src/components/nameEdit.tsx | 11 +++-- .../src/components/colorBrowser.tsx | 6 +-- .../09_Sidebar/src/components/colorPicker.tsx | 10 ++--- hooks/09_Sidebar/src/components/hello.tsx | 2 +- hooks/09_Sidebar/src/components/nameEdit.tsx | 11 +++-- hooks/09_Sidebar/src/components/sidebar.tsx | 6 +-- .../src/components/colorBrowser.tsx | 6 +-- .../src/components/colorPicker.tsx | 10 ++--- hooks/10_TableMock/src/components/hello.tsx | 2 +- .../10_TableMock/src/components/nameEdit.tsx | 11 +++-- .../src/components/colorBrowser.tsx | 6 +-- .../src/components/colorPicker.tsx | 10 ++--- hooks/11_TableAxios/src/components/hello.tsx | 2 +- .../11_TableAxios/src/components/nameEdit.tsx | 11 +++-- .../13_LoginForm/src/common/notification.tsx | 14 +++---- hooks/13_LoginForm/src/pages/loginPage.tsx | 22 +++++----- .../src/common/notification.tsx | 14 +++---- .../src/common/textFieldForm.tsx | 8 ++-- .../14_FormValidation/src/pages/loginPage.tsx | 30 ++++++------- hooks/15_Context/src/common/notification.tsx | 14 +++---- .../15_Context/src/common/sessionContext.tsx | 6 +-- hooks/15_Context/src/common/textFieldForm.tsx | 8 ++-- hooks/15_Context/src/pages/loginPage.tsx | 42 ++++++++----------- 39 files changed, 148 insertions(+), 169 deletions(-) diff --git a/hooks/02_Properties/src/hello.tsx b/hooks/02_Properties/src/hello.tsx index 38df41c1..b9b1d810 100644 --- a/hooks/02_Properties/src/hello.tsx +++ b/hooks/02_Properties/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => ( -

Hello user: {props.userName} !

-); \ No newline at end of file +export const HelloComponent: React.FC = (props) => ( +

Hello user: {props.userName} !

+); diff --git a/hooks/03_State/src/hello.tsx b/hooks/03_State/src/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/03_State/src/hello.tsx +++ b/hooks/03_State/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/03_State/src/nameEdit.tsx b/hooks/03_State/src/nameEdit.tsx index 09c4cd1c..02f7e36d 100644 --- a/hooks/03_State/src/nameEdit.tsx +++ b/hooks/03_State/src/nameEdit.tsx @@ -5,7 +5,7 @@ interface Props { onChange: (e: React.ChangeEvent) => void; } -export const NameEditComponent = (props: Props) => ( +export const NameEditComponent: React.FC = (props) => ( <> diff --git a/hooks/04_Callback/src/hello.tsx b/hooks/04_Callback/src/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/04_Callback/src/hello.tsx +++ b/hooks/04_Callback/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/04_Callback/src/nameEdit.tsx b/hooks/04_Callback/src/nameEdit.tsx index 53edae95..8b1a5ca8 100644 --- a/hooks/04_Callback/src/nameEdit.tsx +++ b/hooks/04_Callback/src/nameEdit.tsx @@ -5,7 +5,7 @@ interface Props { onNameUpdated: (newName: string) => any; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const [editingName, setEditingName] = React.useState(props.initialUserName); const onChange = (e: React.ChangeEvent) => { diff --git a/hooks/05_Refactor/src/hello.tsx b/hooks/05_Refactor/src/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/05_Refactor/src/hello.tsx +++ b/hooks/05_Refactor/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/05_Refactor/src/nameEdit.tsx b/hooks/05_Refactor/src/nameEdit.tsx index 57f53dd0..c2eebf31 100644 --- a/hooks/05_Refactor/src/nameEdit.tsx +++ b/hooks/05_Refactor/src/nameEdit.tsx @@ -7,7 +7,7 @@ interface Props { onEditingNameUpdated: (newEditingName: string) => any; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; diff --git a/hooks/06_Enable/src/hello.tsx b/hooks/06_Enable/src/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/06_Enable/src/hello.tsx +++ b/hooks/06_Enable/src/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/06_Enable/src/nameEdit.tsx b/hooks/06_Enable/src/nameEdit.tsx index 646a4d26..7f9091e3 100644 --- a/hooks/06_Enable/src/nameEdit.tsx +++ b/hooks/06_Enable/src/nameEdit.tsx @@ -5,10 +5,10 @@ interface Props { editingName: string; onNameUpdated: () => any; onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; + disabled: boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; @@ -21,10 +21,9 @@ export const NameEditComponent = (props: Props) => { <> - + ); }; diff --git a/hooks/07_ColorPicker/src/components/colorBrowser.tsx b/hooks/07_ColorPicker/src/components/colorBrowser.tsx index 7dcc3905..813746ce 100644 --- a/hooks/07_ColorPicker/src/components/colorBrowser.tsx +++ b/hooks/07_ColorPicker/src/components/colorBrowser.tsx @@ -5,13 +5,11 @@ interface Props { color: Color; } -export const ColorBrowser = (props: Props) => { +export const ColorBrowser: React.FC = (props) => { const divStyle: React.CSSProperties = { width: "11rem", height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${ - props.color.blue - })` + backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, }; return
; diff --git a/hooks/07_ColorPicker/src/components/colorPicker.tsx b/hooks/07_ColorPicker/src/components/colorPicker.tsx index 91283505..23bdca3c 100644 --- a/hooks/07_ColorPicker/src/components/colorPicker.tsx +++ b/hooks/07_ColorPicker/src/components/colorPicker.tsx @@ -6,7 +6,7 @@ interface Props { onColorUpdated: (color: Color) => void; } -export const ColorPicker = (props: Props) => ( +export const ColorPicker: React.FC = (props) => (
{ +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/07_ColorPicker/src/components/nameEdit.tsx b/hooks/07_ColorPicker/src/components/nameEdit.tsx index 646a4d26..5461073e 100644 --- a/hooks/07_ColorPicker/src/components/nameEdit.tsx +++ b/hooks/07_ColorPicker/src/components/nameEdit.tsx @@ -8,7 +8,7 @@ interface Props { disabled : boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; diff --git a/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx b/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx index 7dcc3905..a28e438e 100644 --- a/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/colorBrowser.tsx @@ -5,7 +5,7 @@ interface Props { color: Color; } -export const ColorBrowser = (props: Props) => { +export const ColorBrowser: React.FC = (props) => { const divStyle: React.CSSProperties = { width: "11rem", height: "7rem", diff --git a/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx b/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx index 945ab4c1..ff4cbcdc 100644 --- a/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/colorPicker.tsx @@ -10,11 +10,11 @@ const updateColor = (props: Props, colorId: keyof Color) => (value: any) => { // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. props.onColorUpdated({ ...props.color, // this creates a clone of the current props.color object... - [colorId]: value // ... which gets one of its properties (colorId) immediately replaced by a new value. + [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. }); }; -export const ColorPicker = (props: Props) => ( +export const ColorPicker: React.FC = (props) => (
void; } -const ColorSliderComponent = (props: PropsColorSlider) => { +const ColorSliderComponent: React.FC = (props: PropsColorSlider) => { return (
{ min="0" max="255" value={props.value} - onChange={event => props.onValueUpdated(+event.target.value)} + onChange={(event) => props.onValueUpdated(+event.target.value)} /> {props.value}
diff --git a/hooks/08_ColorPickerRefactor/src/components/hello.tsx b/hooks/08_ColorPickerRefactor/src/components/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/08_ColorPickerRefactor/src/components/hello.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx b/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx index 646a4d26..7f9091e3 100644 --- a/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx +++ b/hooks/08_ColorPickerRefactor/src/components/nameEdit.tsx @@ -5,10 +5,10 @@ interface Props { editingName: string; onNameUpdated: () => any; onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; + disabled: boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; @@ -21,10 +21,9 @@ export const NameEditComponent = (props: Props) => { <> - + ); }; diff --git a/hooks/09_Sidebar/src/components/colorBrowser.tsx b/hooks/09_Sidebar/src/components/colorBrowser.tsx index 7dcc3905..813746ce 100644 --- a/hooks/09_Sidebar/src/components/colorBrowser.tsx +++ b/hooks/09_Sidebar/src/components/colorBrowser.tsx @@ -5,13 +5,11 @@ interface Props { color: Color; } -export const ColorBrowser = (props: Props) => { +export const ColorBrowser: React.FC = (props) => { const divStyle: React.CSSProperties = { width: "11rem", height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${ - props.color.blue - })` + backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, }; return
; diff --git a/hooks/09_Sidebar/src/components/colorPicker.tsx b/hooks/09_Sidebar/src/components/colorPicker.tsx index ea449834..4346cd4d 100644 --- a/hooks/09_Sidebar/src/components/colorPicker.tsx +++ b/hooks/09_Sidebar/src/components/colorPicker.tsx @@ -6,15 +6,15 @@ interface Props { onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => value => { +const updateColor = (props: Props, colorId: keyof Color) => (value) => { // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. props.onColorUpdated({ ...props.color, // this creates a clone of the current props.color object... - [colorId]: value // ... which gets one of its properties (colorId) immediately replaced by a new value. + [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. }); }; -export const ColorPicker = (props: Props) => ( +export const ColorPicker: React.FC = (props) => (
void; } -const ColorSliderComponent = (props: PropsColorSlider) => { +const ColorSliderComponent: React.FC = (props) => { return (
{ min="0" max="255" value={props.value} - onChange={event => props.onValueUpdated(+event.target.value)} + onChange={(event) => props.onValueUpdated(+event.target.value)} /> {props.value}
diff --git a/hooks/09_Sidebar/src/components/hello.tsx b/hooks/09_Sidebar/src/components/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/09_Sidebar/src/components/hello.tsx +++ b/hooks/09_Sidebar/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/09_Sidebar/src/components/nameEdit.tsx b/hooks/09_Sidebar/src/components/nameEdit.tsx index 646a4d26..7f9091e3 100644 --- a/hooks/09_Sidebar/src/components/nameEdit.tsx +++ b/hooks/09_Sidebar/src/components/nameEdit.tsx @@ -5,10 +5,10 @@ interface Props { editingName: string; onNameUpdated: () => any; onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; + disabled: boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; @@ -21,10 +21,9 @@ export const NameEditComponent = (props: Props) => { <> - + ); }; diff --git a/hooks/09_Sidebar/src/components/sidebar.tsx b/hooks/09_Sidebar/src/components/sidebar.tsx index 762991eb..0847a552 100644 --- a/hooks/09_Sidebar/src/components/sidebar.tsx +++ b/hooks/09_Sidebar/src/components/sidebar.tsx @@ -7,13 +7,11 @@ interface Props { } const divStyle = (props: Props): React.CSSProperties => ({ - width: props.isVisible ? "23rem" : "0rem" + width: props.isVisible ? "23rem" : "0rem", }); -export const SidebarComponent: React.StatelessComponent = props => ( +export const SidebarComponent: React.StatelessComponent = (props) => (
{props.children}
); - - diff --git a/hooks/10_TableMock/src/components/colorBrowser.tsx b/hooks/10_TableMock/src/components/colorBrowser.tsx index 7dcc3905..813746ce 100644 --- a/hooks/10_TableMock/src/components/colorBrowser.tsx +++ b/hooks/10_TableMock/src/components/colorBrowser.tsx @@ -5,13 +5,11 @@ interface Props { color: Color; } -export const ColorBrowser = (props: Props) => { +export const ColorBrowser: React.FC = (props) => { const divStyle: React.CSSProperties = { width: "11rem", height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${ - props.color.blue - })` + backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, }; return
; diff --git a/hooks/10_TableMock/src/components/colorPicker.tsx b/hooks/10_TableMock/src/components/colorPicker.tsx index ea449834..4346cd4d 100644 --- a/hooks/10_TableMock/src/components/colorPicker.tsx +++ b/hooks/10_TableMock/src/components/colorPicker.tsx @@ -6,15 +6,15 @@ interface Props { onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => value => { +const updateColor = (props: Props, colorId: keyof Color) => (value) => { // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. props.onColorUpdated({ ...props.color, // this creates a clone of the current props.color object... - [colorId]: value // ... which gets one of its properties (colorId) immediately replaced by a new value. + [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. }); }; -export const ColorPicker = (props: Props) => ( +export const ColorPicker: React.FC = (props) => (
void; } -const ColorSliderComponent = (props: PropsColorSlider) => { +const ColorSliderComponent: React.FC = (props) => { return (
{ min="0" max="255" value={props.value} - onChange={event => props.onValueUpdated(+event.target.value)} + onChange={(event) => props.onValueUpdated(+event.target.value)} /> {props.value}
diff --git a/hooks/10_TableMock/src/components/hello.tsx b/hooks/10_TableMock/src/components/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/10_TableMock/src/components/hello.tsx +++ b/hooks/10_TableMock/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/10_TableMock/src/components/nameEdit.tsx b/hooks/10_TableMock/src/components/nameEdit.tsx index 646a4d26..7f9091e3 100644 --- a/hooks/10_TableMock/src/components/nameEdit.tsx +++ b/hooks/10_TableMock/src/components/nameEdit.tsx @@ -5,10 +5,10 @@ interface Props { editingName: string; onNameUpdated: () => any; onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; + disabled: boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; @@ -21,10 +21,9 @@ export const NameEditComponent = (props: Props) => { <> - + ); }; diff --git a/hooks/11_TableAxios/src/components/colorBrowser.tsx b/hooks/11_TableAxios/src/components/colorBrowser.tsx index 7dcc3905..813746ce 100644 --- a/hooks/11_TableAxios/src/components/colorBrowser.tsx +++ b/hooks/11_TableAxios/src/components/colorBrowser.tsx @@ -5,13 +5,11 @@ interface Props { color: Color; } -export const ColorBrowser = (props: Props) => { +export const ColorBrowser: React.FC = (props) => { const divStyle: React.CSSProperties = { width: "11rem", height: "7rem", - backgroundColor: `rgb(${props.color.red},${props.color.green}, ${ - props.color.blue - })` + backgroundColor: `rgb(${props.color.red},${props.color.green}, ${props.color.blue})`, }; return
; diff --git a/hooks/11_TableAxios/src/components/colorPicker.tsx b/hooks/11_TableAxios/src/components/colorPicker.tsx index ea449834..4346cd4d 100644 --- a/hooks/11_TableAxios/src/components/colorPicker.tsx +++ b/hooks/11_TableAxios/src/components/colorPicker.tsx @@ -6,15 +6,15 @@ interface Props { onColorUpdated: (color: Color) => void; } -const updateColor = (props: Props, colorId: keyof Color) => value => { +const updateColor = (props: Props, colorId: keyof Color) => (value) => { // keyof Color ensures only 'red', 'blue' or 'green' can be passed in. props.onColorUpdated({ ...props.color, // this creates a clone of the current props.color object... - [colorId]: value // ... which gets one of its properties (colorId) immediately replaced by a new value. + [colorId]: value, // ... which gets one of its properties (colorId) immediately replaced by a new value. }); }; -export const ColorPicker = (props: Props) => ( +export const ColorPicker: React.FC = (props) => (
void; } -const ColorSliderComponent = (props: PropsColorSlider) => { +const ColorSliderComponent: React.FC = (props) => { return (
{ min="0" max="255" value={props.value} - onChange={event => props.onValueUpdated(+event.target.value)} + onChange={(event) => props.onValueUpdated(+event.target.value)} /> {props.value}
diff --git a/hooks/11_TableAxios/src/components/hello.tsx b/hooks/11_TableAxios/src/components/hello.tsx index 33a0ab73..b6b7aca4 100644 --- a/hooks/11_TableAxios/src/components/hello.tsx +++ b/hooks/11_TableAxios/src/components/hello.tsx @@ -4,6 +4,6 @@ interface Props { userName: string; } -export const HelloComponent = (props: Props) => { +export const HelloComponent: React.FC = (props) => { return

Hello user: {props.userName} !

; }; diff --git a/hooks/11_TableAxios/src/components/nameEdit.tsx b/hooks/11_TableAxios/src/components/nameEdit.tsx index 646a4d26..7f9091e3 100644 --- a/hooks/11_TableAxios/src/components/nameEdit.tsx +++ b/hooks/11_TableAxios/src/components/nameEdit.tsx @@ -5,10 +5,10 @@ interface Props { editingName: string; onNameUpdated: () => any; onEditingNameUpdated: (newEditingName: string) => any; - disabled : boolean; + disabled: boolean; } -export const NameEditComponent = (props: Props) => { +export const NameEditComponent: React.FC = (props) => { const onChange = (e: React.ChangeEvent) => { props.onEditingNameUpdated(e.target.value); }; @@ -21,10 +21,9 @@ export const NameEditComponent = (props: Props) => { <> - + ); }; diff --git a/hooks/13_LoginForm/src/common/notification.tsx b/hooks/13_LoginForm/src/common/notification.tsx index 3fc14394..7f1a3336 100644 --- a/hooks/13_LoginForm/src/common/notification.tsx +++ b/hooks/13_LoginForm/src/common/notification.tsx @@ -11,15 +11,15 @@ interface Props { onClose: () => void; } -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ close: { - padding: theme.spacing(0.5) - } + padding: theme.spacing(0.5), + }, }) ); -export const NotificationComponent = (props: Props) => { +export const NotificationComponent: React.FC = (props) => { const classes = useStyles(); const { message, show, onClose } = props; @@ -27,13 +27,13 @@ export const NotificationComponent = (props: Props) => { {message}} action={[ @@ -45,7 +45,7 @@ export const NotificationComponent = (props: Props) => { onClick={onClose} > - + , ]} /> ); diff --git a/hooks/13_LoginForm/src/pages/loginPage.tsx b/hooks/13_LoginForm/src/pages/loginPage.tsx index a6fbf0cf..9caa627d 100644 --- a/hooks/13_LoginForm/src/pages/loginPage.tsx +++ b/hooks/13_LoginForm/src/pages/loginPage.tsx @@ -12,18 +12,18 @@ import { isValidLogin } from "../api/login"; import { NotificationComponent } from "../common"; // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ card: { maxWidth: 400, - margin: "0 auto" - } + margin: "0 auto", + }, }) ); -interface Props {}; +interface Props {} -export const LoginPage = (props: Props) => { +export const LoginPage: React.FC = (props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); @@ -42,7 +42,7 @@ export const LoginPage = (props: Props) => { const onUpdateLoginField = (name, value) => { setLoginInfo({ ...loginInfo, - [name]: value + [name]: value, }); }; @@ -74,22 +74,22 @@ interface PropsForm { } // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles(theme => +const useFormStyles = makeStyles((theme) => createStyles({ formContainer: { display: "flex", flexDirection: "column", - justifyContent: "center" - } + justifyContent: "center", + }, }) ); -const LoginForm = (props: PropsForm) => { +const LoginForm: React.FC = (props) => { const classes = useFormStyles(); const { onLogin, onUpdateField, loginInfo } = props; // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = fieldId => e => { + const onTexFieldChange = (fieldId) => (e) => { onUpdateField(fieldId, e.target.value); }; diff --git a/hooks/14_FormValidation/src/common/notification.tsx b/hooks/14_FormValidation/src/common/notification.tsx index 3fc14394..7f1a3336 100644 --- a/hooks/14_FormValidation/src/common/notification.tsx +++ b/hooks/14_FormValidation/src/common/notification.tsx @@ -11,15 +11,15 @@ interface Props { onClose: () => void; } -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ close: { - padding: theme.spacing(0.5) - } + padding: theme.spacing(0.5), + }, }) ); -export const NotificationComponent = (props: Props) => { +export const NotificationComponent: React.FC = (props) => { const classes = useStyles(); const { message, show, onClose } = props; @@ -27,13 +27,13 @@ export const NotificationComponent = (props: Props) => { {message}} action={[ @@ -45,7 +45,7 @@ export const NotificationComponent = (props: Props) => { onClick={onClose} > - + , ]} /> ); diff --git a/hooks/14_FormValidation/src/common/textFieldForm.tsx b/hooks/14_FormValidation/src/common/textFieldForm.tsx index 221010ef..5be9a8be 100644 --- a/hooks/14_FormValidation/src/common/textFieldForm.tsx +++ b/hooks/14_FormValidation/src/common/textFieldForm.tsx @@ -12,17 +12,17 @@ interface Props { } const defaultProps: Partial = { - type: "text" + type: "text", }; const onTextFieldChange = ( fieldId: string, onChange: (fieldId, value) => void -) => e => { +) => (e) => { onChange(fieldId, e.target.value); }; -export const TextFieldForm: React.StatelessComponent = props => { +export const TextFieldForm: React.StatelessComponent = (props) => { const { name, label, onChange, value, error, type } = props; return ( <> @@ -34,7 +34,7 @@ export const TextFieldForm: React.StatelessComponent = props => { onChange={onTextFieldChange(name, onChange)} /> - {props.error} + {error} ); diff --git a/hooks/14_FormValidation/src/pages/loginPage.tsx b/hooks/14_FormValidation/src/pages/loginPage.tsx index 09f017c3..03567eac 100644 --- a/hooks/14_FormValidation/src/pages/loginPage.tsx +++ b/hooks/14_FormValidation/src/pages/loginPage.tsx @@ -14,24 +14,24 @@ import { isValidLogin } from "../api/login"; import { NotificationComponent } from "../common"; import { LoginFormErrors, - createDefaultLoginFormErrors + createDefaultLoginFormErrors, } from "./loginPage.viewmodel"; import { loginFormValidation } from "./loginPage.validation"; import { TextFieldForm } from "../common"; // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ card: { maxWidth: 400, - margin: "0 auto" - } + margin: "0 auto", + }, }) ); interface Props {} -export const LoginPage = (props: Props) => { +export const LoginPage: React.FC = (props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); @@ -43,7 +43,7 @@ export const LoginPage = (props: Props) => { const history = useHistory(); const onLogin = () => { - loginFormValidation.validateForm(loginInfo).then(formValidationResult => { + loginFormValidation.validateForm(loginInfo).then((formValidationResult) => { if (formValidationResult.succeeded) { if (isValidLogin(loginInfo)) { history.push("/pageB"); @@ -54,7 +54,7 @@ export const LoginPage = (props: Props) => { alert("error, review the fields"); const updatedLoginFormErrors = { ...loginFormErrors, - ...formValidationResult.fieldErrors + ...formValidationResult.fieldErrors, }; setLoginFormErrors(updatedLoginFormErrors); } @@ -64,15 +64,15 @@ export const LoginPage = (props: Props) => { const onUpdateLoginField = (name, value) => { setLoginInfo({ ...loginInfo, - [name]: value + [name]: value, }); loginFormValidation .validateField(loginInfo, name, value) - .then(fieldValidationResult => { + .then((fieldValidationResult) => { setLoginFormErrors({ ...loginFormErrors, - [name]: fieldValidationResult + [name]: fieldValidationResult, }); }); }; @@ -107,22 +107,22 @@ interface PropsForm { } // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles(theme => +const useFormStyles = makeStyles((theme) => createStyles({ formContainer: { display: "flex", flexDirection: "column", - justifyContent: "center" - } + justifyContent: "center", + }, }) ); -const LoginForm = (props: PropsForm) => { +const LoginForm: React.FC = (props) => { const classes = useFormStyles(); const { onLogin, onUpdateField, loginInfo, loginFormErrors } = props; // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = fieldId => e => { + const onTexFieldChange = (fieldId) => (e) => { onUpdateField(fieldId, e.target.value); }; diff --git a/hooks/15_Context/src/common/notification.tsx b/hooks/15_Context/src/common/notification.tsx index 3fc14394..7f1a3336 100644 --- a/hooks/15_Context/src/common/notification.tsx +++ b/hooks/15_Context/src/common/notification.tsx @@ -11,15 +11,15 @@ interface Props { onClose: () => void; } -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ close: { - padding: theme.spacing(0.5) - } + padding: theme.spacing(0.5), + }, }) ); -export const NotificationComponent = (props: Props) => { +export const NotificationComponent: React.FC = (props) => { const classes = useStyles(); const { message, show, onClose } = props; @@ -27,13 +27,13 @@ export const NotificationComponent = (props: Props) => { {message}} action={[ @@ -45,7 +45,7 @@ export const NotificationComponent = (props: Props) => { onClick={onClose} > - + , ]} /> ); diff --git a/hooks/15_Context/src/common/sessionContext.tsx b/hooks/15_Context/src/common/sessionContext.tsx index 4d1c0384..4edab12f 100644 --- a/hooks/15_Context/src/common/sessionContext.tsx +++ b/hooks/15_Context/src/common/sessionContext.tsx @@ -7,18 +7,18 @@ export interface SessionContextProps { export const createDefaultUser = (): SessionContextProps => ({ login: "no user", - updateLogin: value => { + updateLogin: (value) => { console.warn( "if you are reading this, likely you forgot to add the provider on top of your app" ); - } + }, }); export const SessionContext = React.createContext( createDefaultUser() ); -export const SessionProvider: React.FunctionComponent = props => { +export const SessionProvider: React.FC = (props) => { const [login, setLogin] = React.useState(""); return ( diff --git a/hooks/15_Context/src/common/textFieldForm.tsx b/hooks/15_Context/src/common/textFieldForm.tsx index 221010ef..5be9a8be 100644 --- a/hooks/15_Context/src/common/textFieldForm.tsx +++ b/hooks/15_Context/src/common/textFieldForm.tsx @@ -12,17 +12,17 @@ interface Props { } const defaultProps: Partial = { - type: "text" + type: "text", }; const onTextFieldChange = ( fieldId: string, onChange: (fieldId, value) => void -) => e => { +) => (e) => { onChange(fieldId, e.target.value); }; -export const TextFieldForm: React.StatelessComponent = props => { +export const TextFieldForm: React.StatelessComponent = (props) => { const { name, label, onChange, value, error, type } = props; return ( <> @@ -34,7 +34,7 @@ export const TextFieldForm: React.StatelessComponent = props => { onChange={onTextFieldChange(name, onChange)} /> - {props.error} + {error} ); diff --git a/hooks/15_Context/src/pages/loginPage.tsx b/hooks/15_Context/src/pages/loginPage.tsx index a2d10824..2d3fed4c 100644 --- a/hooks/15_Context/src/pages/loginPage.tsx +++ b/hooks/15_Context/src/pages/loginPage.tsx @@ -1,38 +1,34 @@ import * as React from "react"; -import { Link } from "react-router-dom"; -import { withRouter, RouteComponentProps } from "react-router-dom"; +import { useHistory } from "react-router-dom"; import makeStyles from "@material-ui/styles/makestyles"; import createStyles from "@material-ui/styles/createStyles"; import Card from "@material-ui/core/Card"; import CardHeader from "@material-ui/core/CardHeader"; import CardContent from "@material-ui/core/CardContent"; -import TextField from "@material-ui/core/TextField"; import Button from "@material-ui/core/Button"; -import { FormHelperText } from "@material-ui/core"; import { LoginEntity, createEmptyLogin } from "../model/login"; import { isValidLogin } from "../api/login"; import { NotificationComponent } from "../common"; import { LoginFormErrors, - createDefaultLoginFormErrors + createDefaultLoginFormErrors, } from "./loginPage.viewmodel"; import { loginFormValidation } from "./loginPage.validation"; import { TextFieldForm, SessionContext } from "../common"; // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles(theme => +const useStyles = makeStyles((theme) => createStyles({ card: { maxWidth: 400, - margin: "0 auto" - } + margin: "0 auto", + }, }) ); -interface Props extends RouteComponentProps {} - -const LoginPageInner = (props: Props) => { +const LoginPage: React.FC = (props) => { const loginContext = React.useContext(SessionContext); + const history = useHistory(); const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() @@ -44,10 +40,10 @@ const LoginPageInner = (props: Props) => { const classes = useStyles(); const onLogin = () => { - loginFormValidation.validateForm(loginInfo).then(formValidationResult => { + loginFormValidation.validateForm(loginInfo).then((formValidationResult) => { if (formValidationResult.succeeded) { if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); + history.push("/pageB"); loginContext.updateLogin(loginInfo.login); } else { setShowLoginFailedMsg(true); @@ -56,7 +52,7 @@ const LoginPageInner = (props: Props) => { alert("error, review the fields"); const updatedLoginFormErrors = { ...loginFormErrors, - ...formValidationResult.fieldErrors + ...formValidationResult.fieldErrors, }; setLoginFormErrors(updatedLoginFormErrors); } @@ -66,15 +62,15 @@ const LoginPageInner = (props: Props) => { const onUpdateLoginField = (name, value) => { setLoginInfo({ ...loginInfo, - [name]: value + [name]: value, }); loginFormValidation .validateField(loginInfo, name, value) - .then(fieldValidationResult => { + .then((fieldValidationResult) => { setLoginFormErrors({ ...loginFormErrors, - [name]: fieldValidationResult + [name]: fieldValidationResult, }); }); }; @@ -101,8 +97,6 @@ const LoginPageInner = (props: Props) => { ); }; -export const LoginPage = withRouter(LoginPageInner); - interface PropsForm { onLogin: () => void; onUpdateField: (string, any) => void; @@ -111,22 +105,22 @@ interface PropsForm { } // https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles(theme => +const useFormStyles = makeStyles((theme) => createStyles({ formContainer: { display: "flex", flexDirection: "column", - justifyContent: "center" - } + justifyContent: "center", + }, }) ); -const LoginForm = (props: PropsForm) => { +const LoginForm: React.FC = (props) => { const classes = useFormStyles(); const { onLogin, onUpdateField, loginInfo, loginFormErrors } = props; // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = fieldId => e => { + const onTexFieldChange = (fieldId) => (e) => { onUpdateField(fieldId, e.target.value); }; From 9da5146729ab28d569ebf5da9f78743a1258f244 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Sat, 25 Jul 2020 13:51:53 +0200 Subject: [PATCH 26/37] ref: #187 adding types --- hooks/04_Callback/src/nameEdit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/04_Callback/src/nameEdit.tsx b/hooks/04_Callback/src/nameEdit.tsx index 8b1a5ca8..b471fd42 100644 --- a/hooks/04_Callback/src/nameEdit.tsx +++ b/hooks/04_Callback/src/nameEdit.tsx @@ -13,7 +13,7 @@ export const NameEditComponent: React.FC = (props) => { }; const onNameSubmit = (event: any): any => { - props.onNameUpdated(editingName); + props. }; return ( From e6b8f88ceaa14bd0c2b3aafb3deaa535bec71627 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Sat, 25 Jul 2020 13:54:43 +0200 Subject: [PATCH 27/37] ref: #187 delete accidentaly --- hooks/04_Callback/src/nameEdit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/04_Callback/src/nameEdit.tsx b/hooks/04_Callback/src/nameEdit.tsx index b471fd42..8b1a5ca8 100644 --- a/hooks/04_Callback/src/nameEdit.tsx +++ b/hooks/04_Callback/src/nameEdit.tsx @@ -13,7 +13,7 @@ export const NameEditComponent: React.FC = (props) => { }; const onNameSubmit = (event: any): any => { - props. + props.onNameUpdated(editingName); }; return ( From b6846947efb302943d289662af4de9f2f165154f Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Sat, 25 Jul 2020 16:10:16 +0200 Subject: [PATCH 28/37] ref: #187 adding formik pendind setLoginInfo --- hooks/14_FormValidation/Readme.md | 29 ++--- hooks/14_FormValidation/package.json | 4 +- .../src/pages/loginFormComponent.tsx | 57 +++++++++ .../14_FormValidation/src/pages/loginPage.tsx | 119 +++--------------- .../src/pages/loginPage.validation.ts | 21 ++-- .../src/pages/loginPage.viewmodel.ts | 11 -- 6 files changed, 98 insertions(+), 143 deletions(-) create mode 100644 hooks/14_FormValidation/src/pages/loginFormComponent.tsx delete mode 100644 hooks/14_FormValidation/src/pages/loginPage.viewmodel.ts diff --git a/hooks/14_FormValidation/Readme.md b/hooks/14_FormValidation/Readme.md index f906f597..8447ad96 100644 --- a/hooks/14_FormValidation/Readme.md +++ b/hooks/14_FormValidation/Readme.md @@ -6,7 +6,7 @@ For this we will use lc-form-validation library Summary steps: -- Install lc-form-validation library. +- Install formik, fonk, fonk-formik library. - Refactor input component to a common component and include error validation info. - Let's define the validation for the form. - Let's hook it. @@ -19,10 +19,10 @@ Summary steps: npm install ``` -- Let's install the _lc-form-validation-library_. +- Let's install the _formik, @lemoncode/fonk, @lemoncode/fonk-formik _. ```bash -npm install lc-form-validation --save +npm install formik @lemoncode/fonk @lemoncode/fonk-formik --save ``` - To avoid having too much repeated code let's move to common an input component, including it's @@ -88,22 +88,17 @@ export * from './notification'; _./src/pages/loginPage.validation.ts_ ```typescript -import { - createFormValidation, - ValidationConstraints, - Validators -} from "lc-form-validation"; - -const loginFormValidationConstraints: ValidationConstraints = { - fields: { - login: [{ validator: Validators.required }], - password: [{ validator: Validators.required }] - } +import { ValidationSchema, Validators } from "@lemoncode/fonk"; +import { createFormikValidation } from "@lemoncode/fonk-formik"; + +const validationSchema: ValidationSchema = { + field: { + login: [Validators.required], + password: [Validators.required], + }, }; -export const loginFormValidation = createFormValidation( - loginFormValidationConstraints -); +export const loginFormValidation = createFormikValidation(validationSchema); ``` - Let's create now a class to hold the dataFormErrors. diff --git a/hooks/14_FormValidation/package.json b/hooks/14_FormValidation/package.json index 1360a87c..79169511 100644 --- a/hooks/14_FormValidation/package.json +++ b/hooks/14_FormValidation/package.json @@ -39,9 +39,11 @@ "webpack-dev-server": "^3.11.0" }, "dependencies": { + "@lemoncode/fonk": "^1.3.0", + "@lemoncode/fonk-formik": "^4.0.1", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", - "lc-form-validation": "^2.0.0", + "formik": "^2.1.5", "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "^5.2.0" diff --git a/hooks/14_FormValidation/src/pages/loginFormComponent.tsx b/hooks/14_FormValidation/src/pages/loginFormComponent.tsx new file mode 100644 index 00000000..5bb57ebe --- /dev/null +++ b/hooks/14_FormValidation/src/pages/loginFormComponent.tsx @@ -0,0 +1,57 @@ +import * as React from "react"; +import { LoginEntity } from "../model/login"; +import { TextFieldForm } from "../common"; +import { Form } from "formik"; +import createStyles from "@material-ui/styles/createStyles"; +import makeStyles from "@material-ui/styles/makeStyles"; +import Button from "@material-ui/core/Button"; + +interface PropsForm { + onLogin: () => void; + onUpdateField: (string, any) => void; + loginInfo: LoginEntity; +} + +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + formContainer: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + }, + }) +); + +export const LoginForm: React.FC = (props) => { + const classes = useFormStyles(); + const { onLogin, onUpdateField, loginInfo } = props; + + // TODO: Enhacement move this outside the stateless component discuss why is a good idea + const onTexFieldChange = (fieldID) => (e) => { + onUpdateField(fieldID, e.target.value); + }; + + return ( +
+
+ + + +
+
+ ); +}; diff --git a/hooks/14_FormValidation/src/pages/loginPage.tsx b/hooks/14_FormValidation/src/pages/loginPage.tsx index 03567eac..9344b27e 100644 --- a/hooks/14_FormValidation/src/pages/loginPage.tsx +++ b/hooks/14_FormValidation/src/pages/loginPage.tsx @@ -1,23 +1,15 @@ import * as React from "react"; -import { Link } from "react-router-dom"; import { useHistory } from "react-router-dom"; import makeStyles from "@material-ui/styles/makeStyles"; import createStyles from "@material-ui/styles/createStyles"; import Card from "@material-ui/core/Card"; import CardHeader from "@material-ui/core/CardHeader"; import CardContent from "@material-ui/core/CardContent"; -import TextField from "@material-ui/core/TextField"; -import Button from "@material-ui/core/Button"; -import { FormHelperText } from "@material-ui/core"; import { LoginEntity, createEmptyLogin } from "../model/login"; import { isValidLogin } from "../api/login"; -import { NotificationComponent } from "../common"; -import { - LoginFormErrors, - createDefaultLoginFormErrors, -} from "./loginPage.viewmodel"; import { loginFormValidation } from "./loginPage.validation"; -import { TextFieldForm } from "../common"; +import { Formik } from "formik"; +import { LoginForm } from "./loginFormComponent"; // https://material-ui.com/styles/api/#makestyles-styles-options-hook const useStyles = makeStyles((theme) => @@ -35,30 +27,13 @@ export const LoginPage: React.FC = (props) => { const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); - const [loginFormErrors, setLoginFormErrors] = React.useState( - createDefaultLoginFormErrors() - ); - const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); const classes = useStyles(); const history = useHistory(); const onLogin = () => { - loginFormValidation.validateForm(loginInfo).then((formValidationResult) => { - if (formValidationResult.succeeded) { - if (isValidLogin(loginInfo)) { - history.push("/pageB"); - } else { - setShowLoginFailedMsg(true); - } - } else { - alert("error, review the fields"); - const updatedLoginFormErrors = { - ...loginFormErrors, - ...formValidationResult.fieldErrors, - }; - setLoginFormErrors(updatedLoginFormErrors); - } - }); + if (isValidLogin(loginInfo)) { + history.push("/pageB"); + } }; const onUpdateLoginField = (name, value) => { @@ -66,15 +41,6 @@ export const LoginPage: React.FC = (props) => { ...loginInfo, [name]: value, }); - - loginFormValidation - .validateField(loginInfo, name, value) - .then((fieldValidationResult) => { - setLoginFormErrors({ - ...loginFormErrors, - [name]: fieldValidationResult, - }); - }); }; return ( @@ -82,70 +48,21 @@ export const LoginPage: React.FC = (props) => { - + + {() => ( + + )} + - setShowLoginFailedMsg(false)} - /> ); }; - -interface PropsForm { - onLogin: () => void; - onUpdateField: (string, any) => void; - loginInfo: LoginEntity; - loginFormErrors: LoginFormErrors; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); - -const LoginForm: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin, onUpdateField, loginInfo, loginFormErrors } = props; - - // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = (fieldId) => (e) => { - onUpdateField(fieldId, e.target.value); - }; - - return ( -
- - - -
- ); -}; diff --git a/hooks/14_FormValidation/src/pages/loginPage.validation.ts b/hooks/14_FormValidation/src/pages/loginPage.validation.ts index ae379b5d..20942129 100644 --- a/hooks/14_FormValidation/src/pages/loginPage.validation.ts +++ b/hooks/14_FormValidation/src/pages/loginPage.validation.ts @@ -1,16 +1,11 @@ -import { - createFormValidation, - ValidationConstraints, - Validators -} from "lc-form-validation"; +import { ValidationSchema, Validators } from "@lemoncode/fonk"; +import { createFormikValidation } from "@lemoncode/fonk-formik"; -const loginFormValidationConstraints: ValidationConstraints = { - fields: { - login: [{ validator: Validators.required }], - password: [{ validator: Validators.required }] - } +const validationSchema: ValidationSchema = { + field: { + login: [Validators.required], + password: [Validators.required], + }, }; -export const loginFormValidation = createFormValidation( - loginFormValidationConstraints -); +export const loginFormValidation = createFormikValidation(validationSchema); diff --git a/hooks/14_FormValidation/src/pages/loginPage.viewmodel.ts b/hooks/14_FormValidation/src/pages/loginPage.viewmodel.ts deleted file mode 100644 index 4b3cf5b4..00000000 --- a/hooks/14_FormValidation/src/pages/loginPage.viewmodel.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { FieldValidationResult } from "lc-form-validation"; - -export interface LoginFormErrors { - login: FieldValidationResult; - password: FieldValidationResult; -} - -export const createDefaultLoginFormErrors = (): LoginFormErrors => ({ - login: new FieldValidationResult(), - password: new FieldValidationResult() -}); From cca74bee4869c2e5bdfefa629ef66793d466390a Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Sat, 25 Jul 2020 18:33:22 +0200 Subject: [PATCH 29/37] ref: #187 adding formik pendind setLoginInfo --- hooks/14_FormValidation/src/pages/loginFormComponent.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hooks/14_FormValidation/src/pages/loginFormComponent.tsx b/hooks/14_FormValidation/src/pages/loginFormComponent.tsx index 5bb57ebe..d2ea4c0b 100644 --- a/hooks/14_FormValidation/src/pages/loginFormComponent.tsx +++ b/hooks/14_FormValidation/src/pages/loginFormComponent.tsx @@ -27,11 +27,6 @@ export const LoginForm: React.FC = (props) => { const classes = useFormStyles(); const { onLogin, onUpdateField, loginInfo } = props; - // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = (fieldID) => (e) => { - onUpdateField(fieldID, e.target.value); - }; - return (
@@ -39,14 +34,14 @@ export const LoginForm: React.FC = (props) => { label="Name" name="login" value={loginInfo.login} - onChange={onTexFieldChange("login")} + onChange={onUpdateField} /> +
+
+ )} + + + + ); +}; diff --git a/hooks/14_FormValidation/src/pages/login.container.tsx b/hooks/14_FormValidation/src/pages/login.container.tsx new file mode 100644 index 00000000..f8c11af9 --- /dev/null +++ b/hooks/14_FormValidation/src/pages/login.container.tsx @@ -0,0 +1,37 @@ +import * as React from "react"; +import { useHistory } from "react-router-dom"; +import { LoginEntity } from "../model/login"; +import { isValidLogin } from "../api/login"; +import { LoginComponent } from "./login.component"; +import { NotificationComponent } from "../common"; + +interface Props {} + +export const LoginContainer: React.FC = (props) => { + const history = useHistory(); + const [isShowAlert, setShowAlert] = React.useState(false); + + const loginSucceeded = (isValid: boolean) => { + if (isValid) { + history.push("/pageB"); + } else { + setShowAlert(true); + } + }; + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); + }; + + return ( + <> + + setShowAlert(false)} + /> + ; + + ); +}; diff --git a/hooks/14_FormValidation/src/pages/loginPage.validation.ts b/hooks/14_FormValidation/src/pages/login.validation.ts similarity index 100% rename from hooks/14_FormValidation/src/pages/loginPage.validation.ts rename to hooks/14_FormValidation/src/pages/login.validation.ts diff --git a/hooks/14_FormValidation/src/pages/loginFormComponent.tsx b/hooks/14_FormValidation/src/pages/loginFormComponent.tsx deleted file mode 100644 index d2ea4c0b..00000000 --- a/hooks/14_FormValidation/src/pages/loginFormComponent.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from "react"; -import { LoginEntity } from "../model/login"; -import { TextFieldForm } from "../common"; -import { Form } from "formik"; -import createStyles from "@material-ui/styles/createStyles"; -import makeStyles from "@material-ui/styles/makeStyles"; -import Button from "@material-ui/core/Button"; - -interface PropsForm { - onLogin: () => void; - onUpdateField: (string, any) => void; - loginInfo: LoginEntity; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); - -export const LoginForm: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin, onUpdateField, loginInfo } = props; - - return ( -
-
- - - -
-
- ); -}; diff --git a/hooks/14_FormValidation/src/pages/loginPage.tsx b/hooks/14_FormValidation/src/pages/loginPage.tsx deleted file mode 100644 index 9344b27e..00000000 --- a/hooks/14_FormValidation/src/pages/loginPage.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import * as React from "react"; -import { useHistory } from "react-router-dom"; -import makeStyles from "@material-ui/styles/makeStyles"; -import createStyles from "@material-ui/styles/createStyles"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import { LoginEntity, createEmptyLogin } from "../model/login"; -import { isValidLogin } from "../api/login"; -import { loginFormValidation } from "./loginPage.validation"; -import { Formik } from "formik"; -import { LoginForm } from "./loginFormComponent"; - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -interface Props {} - -export const LoginPage: React.FC = (props) => { - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); - const classes = useStyles(); - const history = useHistory(); - - const onLogin = () => { - if (isValidLogin(loginInfo)) { - history.push("/pageB"); - } - }; - - const onUpdateLoginField = (name, value) => { - setLoginInfo({ - ...loginInfo, - [name]: value, - }); - }; - - return ( - <> - - - - - {() => ( - - )} - - - - - ); -}; From 292d24d31b13c2334ae12f2b930761c4525d8678 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Wed, 12 Aug 2020 11:38:40 +0200 Subject: [PATCH 31/37] ref:#187 14_FormValidation semicolon typo --- hooks/14_FormValidation/src/pages/login.container.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/hooks/14_FormValidation/src/pages/login.container.tsx b/hooks/14_FormValidation/src/pages/login.container.tsx index f8c11af9..eef45302 100644 --- a/hooks/14_FormValidation/src/pages/login.container.tsx +++ b/hooks/14_FormValidation/src/pages/login.container.tsx @@ -31,7 +31,6 @@ export const LoginContainer: React.FC = (props) => { message="Invalid Form" onClose={() => setShowAlert(false)} /> - ; ); }; From 722a324b326f092320fd1671d513fc47260971f0 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Wed, 12 Aug 2020 11:39:27 +0200 Subject: [PATCH 32/37] ref:#187 14_FormValidation top message --- hooks/14_FormValidation/src/common/notification.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/14_FormValidation/src/common/notification.tsx b/hooks/14_FormValidation/src/common/notification.tsx index 7f1a3336..50e2b706 100644 --- a/hooks/14_FormValidation/src/common/notification.tsx +++ b/hooks/14_FormValidation/src/common/notification.tsx @@ -26,8 +26,8 @@ export const NotificationComponent: React.FC = (props) => { return ( Date: Wed, 12 Aug 2020 12:22:51 +0200 Subject: [PATCH 33/37] ref:#187 15 adding context form validation --- hooks/15_Context/package.json | 4 +- hooks/15_Context/src/api/login.ts | 11 +- hooks/15_Context/src/app.tsx | 4 +- hooks/15_Context/src/common/index.ts | 2 +- hooks/15_Context/src/common/notification.tsx | 4 +- .../src/common/textField.component.tsx | 25 +++ hooks/15_Context/src/common/textFieldForm.tsx | 41 ----- .../15_Context/src/pages/login.component.tsx | 65 ++++++++ .../15_Context/src/pages/login.container.tsx | 39 +++++ .../15_Context/src/pages/login.validation.ts | 11 ++ hooks/15_Context/src/pages/loginPage.tsx | 149 ------------------ .../src/pages/loginPage.validation.ts | 16 -- .../src/pages/loginPage.viewmodel.ts | 11 -- hooks/15_Context/src/pages/pageB.tsx | 2 +- 14 files changed, 157 insertions(+), 227 deletions(-) create mode 100644 hooks/15_Context/src/common/textField.component.tsx delete mode 100644 hooks/15_Context/src/common/textFieldForm.tsx create mode 100644 hooks/15_Context/src/pages/login.component.tsx create mode 100644 hooks/15_Context/src/pages/login.container.tsx create mode 100644 hooks/15_Context/src/pages/login.validation.ts delete mode 100644 hooks/15_Context/src/pages/loginPage.tsx delete mode 100644 hooks/15_Context/src/pages/loginPage.validation.ts delete mode 100644 hooks/15_Context/src/pages/loginPage.viewmodel.ts diff --git a/hooks/15_Context/package.json b/hooks/15_Context/package.json index 1360a87c..79169511 100644 --- a/hooks/15_Context/package.json +++ b/hooks/15_Context/package.json @@ -39,9 +39,11 @@ "webpack-dev-server": "^3.11.0" }, "dependencies": { + "@lemoncode/fonk": "^1.3.0", + "@lemoncode/fonk-formik": "^4.0.1", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", - "lc-form-validation": "^2.0.0", + "formik": "^2.1.5", "react": "^16.13.1", "react-dom": "^16.13.1", "react-router-dom": "^5.2.0" diff --git a/hooks/15_Context/src/api/login.ts b/hooks/15_Context/src/api/login.ts index 1f7d4f3b..6fd3e26c 100644 --- a/hooks/15_Context/src/api/login.ts +++ b/hooks/15_Context/src/api/login.ts @@ -1,5 +1,10 @@ -import {LoginEntity} from '../model/login'; +import { LoginEntity } from "../model/login"; // Just a fake loginAPI -export const isValidLogin = (loginInfo : LoginEntity) : boolean => - (loginInfo.login === 'admin' && loginInfo.password === 'test'); +export const isValidLogin = (loginInfo: LoginEntity): Promise => + new Promise((resolve) => { + setTimeout(() => { + // mock call + resolve(loginInfo.login === "admin" && loginInfo.password === "test"); + }, 500); + }); diff --git a/hooks/15_Context/src/app.tsx b/hooks/15_Context/src/app.tsx index 44bd6549..89ae2660 100644 --- a/hooks/15_Context/src/app.tsx +++ b/hooks/15_Context/src/app.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { HashRouter, Switch, Route } from "react-router-dom"; -import { LoginPage } from "./pages/loginPage"; +import { LoginContainer } from "./pages/login.container"; import { PageB } from "./pages/pageB"; import { SessionProvider } from "./common"; @@ -10,7 +10,7 @@ export const App = () => { - + diff --git a/hooks/15_Context/src/common/index.ts b/hooks/15_Context/src/common/index.ts index c6185541..feefdf2a 100644 --- a/hooks/15_Context/src/common/index.ts +++ b/hooks/15_Context/src/common/index.ts @@ -1,3 +1,3 @@ export * from "./notification"; -export * from "./textFieldForm"; +export * from "./textField.component"; export * from "./sessionContext"; diff --git a/hooks/15_Context/src/common/notification.tsx b/hooks/15_Context/src/common/notification.tsx index 7f1a3336..50e2b706 100644 --- a/hooks/15_Context/src/common/notification.tsx +++ b/hooks/15_Context/src/common/notification.tsx @@ -26,8 +26,8 @@ export const NotificationComponent: React.FC = (props) => { return ( = (props) => { + const [field, meta] = useField(props.name); + const textFieldProps = Boolean(field) ? field : props; + const hasError = Boolean(meta && meta.touched && meta.error); + + return ( + <> + + + ); +}; diff --git a/hooks/15_Context/src/common/textFieldForm.tsx b/hooks/15_Context/src/common/textFieldForm.tsx deleted file mode 100644 index 5be9a8be..00000000 --- a/hooks/15_Context/src/common/textFieldForm.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as React from "react"; -import TextField from "@material-ui/core/TextField"; -import Typography from "@material-ui/core/Typography/Typography"; - -interface Props { - name: string; - label: string; - onChange: any; - value: string; - error?: string; - type?: string; -} - -const defaultProps: Partial = { - type: "text", -}; - -const onTextFieldChange = ( - fieldId: string, - onChange: (fieldId, value) => void -) => (e) => { - onChange(fieldId, e.target.value); -}; - -export const TextFieldForm: React.StatelessComponent = (props) => { - const { name, label, onChange, value, error, type } = props; - return ( - <> - - - {error} - - - ); -}; diff --git a/hooks/15_Context/src/pages/login.component.tsx b/hooks/15_Context/src/pages/login.component.tsx new file mode 100644 index 00000000..8af9f671 --- /dev/null +++ b/hooks/15_Context/src/pages/login.component.tsx @@ -0,0 +1,65 @@ +import * as React from "react"; +import { LoginEntity, createEmptyLogin } from "../model/login"; +import { TextFieldComponent } from "../common"; +import { Form } from "formik"; +import createStyles from "@material-ui/styles/createStyles"; +import makeStyles from "@material-ui/styles/makeStyles"; +import Button from "@material-ui/core/Button"; +import Card from "@material-ui/core/Card"; +import CardHeader from "@material-ui/core/CardHeader"; +import CardContent from "@material-ui/core/CardContent"; +import { loginFormValidation } from "./login.validation"; +import { Formik } from "formik"; + +interface PropsForm { + onLogin: (login: LoginEntity) => void; +} + +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + formContainer: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + }, + card: { + maxWidth: 400, + margin: "0 auto", + }, + }) +); + +export const LoginComponent: React.FC = (props) => { + const classes = useFormStyles(); + const { onLogin } = props; + + return ( + + + + + {() => ( +
+
+ + + +
+
+ )} +
+
+
+ ); +}; diff --git a/hooks/15_Context/src/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx new file mode 100644 index 00000000..76e13d30 --- /dev/null +++ b/hooks/15_Context/src/pages/login.container.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { useHistory } from "react-router-dom"; +import { LoginEntity } from "../model/login"; +import { isValidLogin } from "../api/login"; +import { LoginComponent } from "./login.component"; +import { NotificationComponent, SessionContext } from "../common"; +import { light } from "@material-ui/core/styles/createPalette"; + +interface Props {} + +export const LoginContainer: React.FC = (props) => { + const loginContext = React.useContext(SessionContext); + const history = useHistory(); + const [isShowAlert, setShowAlert] = React.useState(false); + + const loginSucceeded = (isValid: boolean, login: LoginEntity) => { + if (isValid) { + history.push("/pageB"); + loginContext.updateLogin(login.login); + } else { + setShowAlert(true); + } + }; + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then((isValid) => loginSucceeded(isValid, login)); + }; + + return ( + <> + + setShowAlert(false)} + /> + + ); +}; diff --git a/hooks/15_Context/src/pages/login.validation.ts b/hooks/15_Context/src/pages/login.validation.ts new file mode 100644 index 00000000..20942129 --- /dev/null +++ b/hooks/15_Context/src/pages/login.validation.ts @@ -0,0 +1,11 @@ +import { ValidationSchema, Validators } from "@lemoncode/fonk"; +import { createFormikValidation } from "@lemoncode/fonk-formik"; + +const validationSchema: ValidationSchema = { + field: { + login: [Validators.required], + password: [Validators.required], + }, +}; + +export const loginFormValidation = createFormikValidation(validationSchema); diff --git a/hooks/15_Context/src/pages/loginPage.tsx b/hooks/15_Context/src/pages/loginPage.tsx deleted file mode 100644 index 2d3fed4c..00000000 --- a/hooks/15_Context/src/pages/loginPage.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import * as React from "react"; -import { useHistory } from "react-router-dom"; -import makeStyles from "@material-ui/styles/makestyles"; -import createStyles from "@material-ui/styles/createStyles"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import Button from "@material-ui/core/Button"; -import { LoginEntity, createEmptyLogin } from "../model/login"; -import { isValidLogin } from "../api/login"; -import { NotificationComponent } from "../common"; -import { - LoginFormErrors, - createDefaultLoginFormErrors, -} from "./loginPage.viewmodel"; -import { loginFormValidation } from "./loginPage.validation"; -import { TextFieldForm, SessionContext } from "../common"; - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -const LoginPage: React.FC = (props) => { - const loginContext = React.useContext(SessionContext); - const history = useHistory(); - - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); - const [loginFormErrors, setLoginFormErrors] = React.useState( - createDefaultLoginFormErrors() - ); - const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); - const classes = useStyles(); - - const onLogin = () => { - loginFormValidation.validateForm(loginInfo).then((formValidationResult) => { - if (formValidationResult.succeeded) { - if (isValidLogin(loginInfo)) { - history.push("/pageB"); - loginContext.updateLogin(loginInfo.login); - } else { - setShowLoginFailedMsg(true); - } - } else { - alert("error, review the fields"); - const updatedLoginFormErrors = { - ...loginFormErrors, - ...formValidationResult.fieldErrors, - }; - setLoginFormErrors(updatedLoginFormErrors); - } - }); - }; - - const onUpdateLoginField = (name, value) => { - setLoginInfo({ - ...loginInfo, - [name]: value, - }); - - loginFormValidation - .validateField(loginInfo, name, value) - .then((fieldValidationResult) => { - setLoginFormErrors({ - ...loginFormErrors, - [name]: fieldValidationResult, - }); - }); - }; - - return ( - <> - - - - - - - setShowLoginFailedMsg(false)} - /> - - ); -}; - -interface PropsForm { - onLogin: () => void; - onUpdateField: (string, any) => void; - loginInfo: LoginEntity; - loginFormErrors: LoginFormErrors; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); - -const LoginForm: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin, onUpdateField, loginInfo, loginFormErrors } = props; - - // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = (fieldId) => (e) => { - onUpdateField(fieldId, e.target.value); - }; - - return ( -
- - - -
- ); -}; diff --git a/hooks/15_Context/src/pages/loginPage.validation.ts b/hooks/15_Context/src/pages/loginPage.validation.ts deleted file mode 100644 index ae379b5d..00000000 --- a/hooks/15_Context/src/pages/loginPage.validation.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { - createFormValidation, - ValidationConstraints, - Validators -} from "lc-form-validation"; - -const loginFormValidationConstraints: ValidationConstraints = { - fields: { - login: [{ validator: Validators.required }], - password: [{ validator: Validators.required }] - } -}; - -export const loginFormValidation = createFormValidation( - loginFormValidationConstraints -); diff --git a/hooks/15_Context/src/pages/loginPage.viewmodel.ts b/hooks/15_Context/src/pages/loginPage.viewmodel.ts deleted file mode 100644 index 4b3cf5b4..00000000 --- a/hooks/15_Context/src/pages/loginPage.viewmodel.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { FieldValidationResult } from "lc-form-validation"; - -export interface LoginFormErrors { - login: FieldValidationResult; - password: FieldValidationResult; -} - -export const createDefaultLoginFormErrors = (): LoginFormErrors => ({ - login: new FieldValidationResult(), - password: new FieldValidationResult() -}); diff --git a/hooks/15_Context/src/pages/pageB.tsx b/hooks/15_Context/src/pages/pageB.tsx index af5c08a3..ccf75980 100644 --- a/hooks/15_Context/src/pages/pageB.tsx +++ b/hooks/15_Context/src/pages/pageB.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { Link } from "react-router-dom"; import { SessionContext } from "../common"; -export const PageB = () => { +export const PageB: React.FC = () => { const loginContext = React.useContext(SessionContext); return ( From 87b2a985d1b6750d58487ec29efc7528bb97b4b9 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Wed, 12 Aug 2020 13:45:43 +0200 Subject: [PATCH 34/37] ref:#187 13 login form change to continue the line of 14 15 --- hooks/13_LoginForm/src/api/login.ts | 11 +- hooks/13_LoginForm/src/app.tsx | 4 +- .../13_LoginForm/src/common/notification.tsx | 4 +- .../src/pages/login.component.tsx | 72 +++++++++++ .../src/pages/login.container.tsx | 36 ++++++ hooks/13_LoginForm/src/pages/loginPage.tsx | 116 ------------------ 6 files changed, 120 insertions(+), 123 deletions(-) create mode 100644 hooks/13_LoginForm/src/pages/login.component.tsx create mode 100644 hooks/13_LoginForm/src/pages/login.container.tsx delete mode 100644 hooks/13_LoginForm/src/pages/loginPage.tsx diff --git a/hooks/13_LoginForm/src/api/login.ts b/hooks/13_LoginForm/src/api/login.ts index 1f7d4f3b..6fd3e26c 100644 --- a/hooks/13_LoginForm/src/api/login.ts +++ b/hooks/13_LoginForm/src/api/login.ts @@ -1,5 +1,10 @@ -import {LoginEntity} from '../model/login'; +import { LoginEntity } from "../model/login"; // Just a fake loginAPI -export const isValidLogin = (loginInfo : LoginEntity) : boolean => - (loginInfo.login === 'admin' && loginInfo.password === 'test'); +export const isValidLogin = (loginInfo: LoginEntity): Promise => + new Promise((resolve) => { + setTimeout(() => { + // mock call + resolve(loginInfo.login === "admin" && loginInfo.password === "test"); + }, 500); + }); diff --git a/hooks/13_LoginForm/src/app.tsx b/hooks/13_LoginForm/src/app.tsx index 9c1b1a24..169d50d8 100644 --- a/hooks/13_LoginForm/src/app.tsx +++ b/hooks/13_LoginForm/src/app.tsx @@ -1,6 +1,6 @@ import * as React from "react"; import { HashRouter, Switch, Route } from "react-router-dom"; -import { LoginPage } from "./pages/loginPage"; +import { LoginContainer } from "./pages/login.container"; import { PageB } from "./pages/pageB"; export const App = () => { @@ -8,7 +8,7 @@ export const App = () => { <> - + diff --git a/hooks/13_LoginForm/src/common/notification.tsx b/hooks/13_LoginForm/src/common/notification.tsx index 7f1a3336..50e2b706 100644 --- a/hooks/13_LoginForm/src/common/notification.tsx +++ b/hooks/13_LoginForm/src/common/notification.tsx @@ -26,8 +26,8 @@ export const NotificationComponent: React.FC = (props) => { return ( void; +} + +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + formContainer: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + }, + card: { + maxWidth: 400, + margin: "0 auto", + }, + }) +); + +export const LoginComponent: React.FC = (props) => { + const { onLogin } = props; + const [loginInfo, setLoginInfo] = React.useState( + createEmptyLogin() + ); + const classes = useFormStyles(); + const onTexFieldChange = (fieldId) => (e) => { + setLoginInfo({ + ...loginInfo, + [fieldId]: e.target.value, + }); + }; + + return ( + + + +
+ + + +
+
+
+ ); +}; diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx new file mode 100644 index 00000000..eef45302 --- /dev/null +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -0,0 +1,36 @@ +import * as React from "react"; +import { useHistory } from "react-router-dom"; +import { LoginEntity } from "../model/login"; +import { isValidLogin } from "../api/login"; +import { LoginComponent } from "./login.component"; +import { NotificationComponent } from "../common"; + +interface Props {} + +export const LoginContainer: React.FC = (props) => { + const history = useHistory(); + const [isShowAlert, setShowAlert] = React.useState(false); + + const loginSucceeded = (isValid: boolean) => { + if (isValid) { + history.push("/pageB"); + } else { + setShowAlert(true); + } + }; + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); + }; + + return ( + <> + + setShowAlert(false)} + /> + + ); +}; diff --git a/hooks/13_LoginForm/src/pages/loginPage.tsx b/hooks/13_LoginForm/src/pages/loginPage.tsx deleted file mode 100644 index 9caa627d..00000000 --- a/hooks/13_LoginForm/src/pages/loginPage.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import * as React from "react"; -import { useHistory } from "react-router-dom"; -import makeStyles from "@material-ui/styles/makeStyles"; -import createStyles from "@material-ui/styles/createStyles"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; -import TextField from "@material-ui/core/TextField"; -import Button from "@material-ui/core/Button"; -import { LoginEntity, createEmptyLogin } from "../model/login"; -import { isValidLogin } from "../api/login"; -import { NotificationComponent } from "../common"; - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useStyles = makeStyles((theme) => - createStyles({ - card: { - maxWidth: 400, - margin: "0 auto", - }, - }) -); - -interface Props {} - -export const LoginPage: React.FC = (props) => { - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); - const history = useHistory(); - const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); - const classes = useStyles(); - - const onLogin = () => { - if (isValidLogin(loginInfo)) { - history.push("/pageB"); - } else { - setShowLoginFailedMsg(true); - } - }; - - const onUpdateLoginField = (name, value) => { - setLoginInfo({ - ...loginInfo, - [name]: value, - }); - }; - - return ( - <> - - - - - - - setShowLoginFailedMsg(false)} - /> - - ); -}; - -interface PropsForm { - onLogin: () => void; - onUpdateField: (name: string, value: any) => void; - loginInfo: LoginEntity; -} - -// https://material-ui.com/styles/api/#makestyles-styles-options-hook -const useFormStyles = makeStyles((theme) => - createStyles({ - formContainer: { - display: "flex", - flexDirection: "column", - justifyContent: "center", - }, - }) -); - -const LoginForm: React.FC = (props) => { - const classes = useFormStyles(); - const { onLogin, onUpdateField, loginInfo } = props; - - // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = (fieldId) => (e) => { - onUpdateField(fieldId, e.target.value); - }; - - return ( -
- - - -
- ); -}; From d14cad38544e1db28cbf71d6226b4f93febb1f30 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Wed, 12 Aug 2020 14:58:14 +0200 Subject: [PATCH 35/37] ref:#187 13, 14, 15 making continue and improve the container --- .../src/pages/login.component.tsx | 56 ++++++++----------- .../src/pages/login.container.tsx | 33 +++++++++-- .../src/pages/login.component.tsx | 54 +++++++----------- .../src/pages/login.container.tsx | 34 +++++++++-- .../15_Context/src/pages/login.component.tsx | 50 +++++++---------- .../15_Context/src/pages/login.container.tsx | 34 ++++++++--- 6 files changed, 146 insertions(+), 115 deletions(-) diff --git a/hooks/13_LoginForm/src/pages/login.component.tsx b/hooks/13_LoginForm/src/pages/login.component.tsx index 1a54103d..c78a4851 100644 --- a/hooks/13_LoginForm/src/pages/login.component.tsx +++ b/hooks/13_LoginForm/src/pages/login.component.tsx @@ -3,9 +3,6 @@ import makeStyles from "@material-ui/styles/makeStyles"; import createStyles from "@material-ui/styles/createStyles"; import TextField from "@material-ui/core/TextField"; import Button from "@material-ui/core/Button"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; import { LoginEntity, createEmptyLogin } from "../model/login"; interface PropsForm { @@ -20,10 +17,6 @@ const useFormStyles = makeStyles((theme) => flexDirection: "column", justifyContent: "center", }, - card: { - maxWidth: 400, - margin: "0 auto", - }, }) ); @@ -41,32 +34,27 @@ export const LoginComponent: React.FC = (props) => { }; return ( - - - -
- - - -
-
-
+
+ + + +
); }; diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index eef45302..0bf329ad 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -3,13 +3,29 @@ import { useHistory } from "react-router-dom"; import { LoginEntity } from "../model/login"; import { isValidLogin } from "../api/login"; import { LoginComponent } from "./login.component"; +import Card from "@material-ui/core/Card"; +import CardHeader from "@material-ui/core/CardHeader"; +import CardContent from "@material-ui/core/CardContent"; +import createStyles from "@material-ui/styles/createStyles"; +import makeStyles from "@material-ui/styles/makeStyles"; import { NotificationComponent } from "../common"; +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + card: { + maxWidth: 400, + margin: "0 auto", + }, + }) +); + interface Props {} export const LoginContainer: React.FC = (props) => { const history = useHistory(); const [isShowAlert, setShowAlert] = React.useState(false); + const classes = useFormStyles(); const loginSucceeded = (isValid: boolean) => { if (isValid) { @@ -25,12 +41,17 @@ export const LoginContainer: React.FC = (props) => { return ( <> - - setShowAlert(false)} - /> + + + + + setShowAlert(false)} + /> + + ); }; diff --git a/hooks/14_FormValidation/src/pages/login.component.tsx b/hooks/14_FormValidation/src/pages/login.component.tsx index 8af9f671..e968d5d6 100644 --- a/hooks/14_FormValidation/src/pages/login.component.tsx +++ b/hooks/14_FormValidation/src/pages/login.component.tsx @@ -5,9 +5,6 @@ import { Form } from "formik"; import createStyles from "@material-ui/styles/createStyles"; import makeStyles from "@material-ui/styles/makeStyles"; import Button from "@material-ui/core/Button"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; import { loginFormValidation } from "./login.validation"; import { Formik } from "formik"; @@ -23,10 +20,6 @@ const useFormStyles = makeStyles((theme) => flexDirection: "column", justifyContent: "center", }, - card: { - maxWidth: 400, - margin: "0 auto", - }, }) ); @@ -35,31 +28,26 @@ export const LoginComponent: React.FC = (props) => { const { onLogin } = props; return ( - - - - - {() => ( -
-
- - - -
-
- )} -
-
-
+ + {() => ( +
+
+ + + +
+
+ )} +
); }; diff --git a/hooks/14_FormValidation/src/pages/login.container.tsx b/hooks/14_FormValidation/src/pages/login.container.tsx index eef45302..55d1f0c5 100644 --- a/hooks/14_FormValidation/src/pages/login.container.tsx +++ b/hooks/14_FormValidation/src/pages/login.container.tsx @@ -3,13 +3,30 @@ import { useHistory } from "react-router-dom"; import { LoginEntity } from "../model/login"; import { isValidLogin } from "../api/login"; import { LoginComponent } from "./login.component"; +import Card from "@material-ui/core/Card"; +import CardHeader from "@material-ui/core/CardHeader"; +import CardContent from "@material-ui/core/CardContent"; +import createStyles from "@material-ui/styles/createStyles"; +import makeStyles from "@material-ui/styles/makeStyles"; import { NotificationComponent } from "../common"; +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + card: { + maxWidth: 400, + margin: "0 auto", + }, + }) +); + +interface Props {} interface Props {} export const LoginContainer: React.FC = (props) => { const history = useHistory(); const [isShowAlert, setShowAlert] = React.useState(false); + const classes = useFormStyles(); const loginSucceeded = (isValid: boolean) => { if (isValid) { @@ -25,12 +42,17 @@ export const LoginContainer: React.FC = (props) => { return ( <> - - setShowAlert(false)} - /> + + + + + setShowAlert(false)} + /> + + ); }; diff --git a/hooks/15_Context/src/pages/login.component.tsx b/hooks/15_Context/src/pages/login.component.tsx index 8af9f671..2c4adb0e 100644 --- a/hooks/15_Context/src/pages/login.component.tsx +++ b/hooks/15_Context/src/pages/login.component.tsx @@ -5,9 +5,6 @@ import { Form } from "formik"; import createStyles from "@material-ui/styles/createStyles"; import makeStyles from "@material-ui/styles/makeStyles"; import Button from "@material-ui/core/Button"; -import Card from "@material-ui/core/Card"; -import CardHeader from "@material-ui/core/CardHeader"; -import CardContent from "@material-ui/core/CardContent"; import { loginFormValidation } from "./login.validation"; import { Formik } from "formik"; @@ -35,31 +32,26 @@ export const LoginComponent: React.FC = (props) => { const { onLogin } = props; return ( - - - - - {() => ( -
-
- - - -
-
- )} -
-
-
+ + {() => ( +
+
+ + + +
+
+ )} +
); }; diff --git a/hooks/15_Context/src/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx index 76e13d30..59574c3f 100644 --- a/hooks/15_Context/src/pages/login.container.tsx +++ b/hooks/15_Context/src/pages/login.container.tsx @@ -3,8 +3,22 @@ import { useHistory } from "react-router-dom"; import { LoginEntity } from "../model/login"; import { isValidLogin } from "../api/login"; import { LoginComponent } from "./login.component"; +import Card from "@material-ui/core/Card"; +import CardHeader from "@material-ui/core/CardHeader"; +import CardContent from "@material-ui/core/CardContent"; +import createStyles from "@material-ui/styles/createStyles"; +import makeStyles from "@material-ui/styles/makeStyles"; import { NotificationComponent, SessionContext } from "../common"; -import { light } from "@material-ui/core/styles/createPalette"; + +// https://material-ui.com/styles/api/#makestyles-styles-options-hook +const useFormStyles = makeStyles((theme) => + createStyles({ + card: { + maxWidth: 400, + margin: "0 auto", + }, + }) +); interface Props {} @@ -12,6 +26,7 @@ export const LoginContainer: React.FC = (props) => { const loginContext = React.useContext(SessionContext); const history = useHistory(); const [isShowAlert, setShowAlert] = React.useState(false); + const classes = useFormStyles(); const loginSucceeded = (isValid: boolean, login: LoginEntity) => { if (isValid) { @@ -28,12 +43,17 @@ export const LoginContainer: React.FC = (props) => { return ( <> - - setShowAlert(false)} - /> + + + + + setShowAlert(false)} + /> + + ); }; From 8269e57a422c47c9bab00dc710e69328a6c69a5b Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 14 Aug 2020 10:35:50 +0200 Subject: [PATCH 36/37] ref:#187 update doc 13 --- hooks/13_LoginForm/Readme.md | 171 +++++++++--------- .../src/pages/login.container.tsx | 2 +- .../src/pages/login.container.tsx | 2 +- .../15_Context/src/pages/login.container.tsx | 2 +- 4 files changed, 92 insertions(+), 85 deletions(-) diff --git a/hooks/13_LoginForm/Readme.md b/hooks/13_LoginForm/Readme.md index b505d8ba..5cef8683 100644 --- a/hooks/13_LoginForm/Readme.md +++ b/hooks/13_LoginForm/Readme.md @@ -18,14 +18,14 @@ npm install - Let's update as well the name of the component. -_./src/pages/loginPage.tsx_ +_./src/pages/login.component.tsx_ ```diff import * as React from "react"; import { Link } from "react-router-dom"; - export const PageA = () => ( -+ export const LoginPage = () => ( ++ export const LoginComponent: React.FC = (props) => {
-

Hello from page A

+

Hello from login Page

@@ -43,7 +43,7 @@ _./src/app.tsx_ import * as React from "react"; import { HashRouter, Switch, Route } from "react-router-dom"; - import { PageA } from "./pages/pageA"; -+ import { LoginPage } from "./pages/loginPage"; ++ import { LoginComponent } from "./pages/login.component"; import { PageB } from "./pages/pageB"; export const App = () => { @@ -53,7 +53,7 @@ export const App = () => { - -+ ++ @@ -118,7 +118,7 @@ npm install @material-ui/core @material-ui/icons --save - Now we could create a login form it could look something like: -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```javascript import * as React from "react"; @@ -143,7 +143,7 @@ const useStyles = makeStyles(theme => interface Props extends RouteComponentProps {} -const LoginPageInner = (props: Props) => { +export const LoginContainer: React.FC = (props) => { const classes = useStyles(); return ( @@ -167,8 +167,6 @@ const LoginPageInner = (props: Props) => { ); }; - -export const LoginPage = withRouter < Props > LoginPageInner; ``` - This can be ok, but if we take a deeper look to this component, we could break down into two, one is the card itself the other the form dialog, so it should finally look like: @@ -186,10 +184,10 @@ export const LoginPage = withRouter < Props > LoginPageInner; - Let's create the LoginForm component (append it to the loginPage file): -_./src/pages/loginPage.tsx_ +_./src/pages/login.component.tsx_ ```javascript -const LoginForm = props => { +export const LoginComponent: React.FC = (props) => { return (
{ justifyContent: "center" }} > - - -
@@ -208,16 +216,16 @@ const LoginForm = props => { }; ``` -- And let's update the _loginPage.tsx_ +- And let's update the _login.container.tsx_ -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff return ( -+ ++ -
- interface Props extends RouteComponentProps {} -const LoginPageInner = (props) => { +export const LoginContainer: React.FC = (props) => { const { classes } = props; + const onLogin = () => { @@ -282,14 +290,13 @@ const LoginPageInner = (props) => { ) } -export const LoginPage = withRouter(LoginPageInner); ``` - Let's add the navigation on button clicked (later on we will check for user and pwd) _form.tsx_. In order to do this we have used react-router 4 "withRouter" HoC (High order component), and pass it down to the LoginForm component. -_./src/pages/loginPage.tsx_ +_./src/pages/login.component.tsx_ ```diff +interface PropsForm { @@ -351,62 +358,59 @@ _./src/api/login.ts_ import { LoginEntity } from "../model/login"; // Just a fake loginAPI -export const isValidLogin = (loginInfo: LoginEntity): boolean => - loginInfo.login === "admin" && loginInfo.password === "test"; +export const isValidLogin = (loginInfo: LoginEntity): Promise => + new Promise((resolve) => { + setTimeout(() => { + // mock call + resolve(loginInfo.login === "admin" && loginInfo.password === "test"); + }, 500); + }); ``` - Let's add the _api_ integration, plus navigation on login succeeded: - First let's create a login state and add the api integration. -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff + import { LoginEntity, createEmptyLogin } from '../model/login'; + import { isValidLogin } from '../api/login'; ``` -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff const LoginPageInner = (props: Props) => { -+ const [loginInfo, setLoginInfo] = React.useState(createEmptyLogin()); ++ const [loginInfo, setLoginInfo] = React.useState( ++ createEmptyLogin() ++ ); const { classes } = props; - const onLogin = () => { -+ if(isValidLogin(loginInfo)) { - props.history.push("/pageB"); -+ } + const loginSucceeded = (isValid: boolean) => { + if (isValid) { + history.push("/pageB"); + } else { + setShowAlert(true); + } + }; + + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then(loginSucceeded); }; ``` - Now let's read the data from the textfields components (user and password). -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff - const onLogin = () => { - if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); - } - }; - -+ const onUpdateLoginField = (name, value) => { -+ setLoginInfo({ -+ ...loginInfo, -+ [name]: value, -+ }) -+ } - return ( - ++ ); @@ -414,23 +418,25 @@ _./src/pages/loginPage.tsx_ - And update _LoginForm_ props and textField onChange. -_./src/pages/loginPage.tsx_ +_./src/pages/login.component.tsx_ ```diff interface PropsForm { - onLogin: () => void; -+ onUpdateField: (name: string, value: any) => void; -+ loginInfo : LoginEntity; ++ onLogin: (login: LoginEntity) => void; } -const LoginForm = (props: PropsForm) => { -- const { onLogin } = props; -+ const { onLogin, onUpdateField, loginInfo } = props; - -+ // TODO: Enhacement move this outside the stateless component discuss why is a good idea +export const LoginComponent: React.FC = (props) => { ++ const [loginInfo, setLoginInfo] = React.useState( ++ const { onLogin } = props; ++ createEmptyLogin() ++ ); ++ const classes = useFormStyles(); + const onTexFieldChange = (fieldId) => (e) => { -+ onUpdateField(fieldId, e.target.value); -+ } ++ setLoginInfo({ ++ ...loginInfo, ++ [fieldId]: e.target.value, ++ }); ++ }; return (
{ justifyContent: "center" }} > - - -
@@ -458,13 +473,11 @@ const LoginForm = (props: PropsForm) => { - We will add material-ui classes to LoginForm component. -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff interface PropsForm { - onLogin: () => void; - onUpdateField: (name: string, value: any) => void; - loginInfo : LoginEntity; + onLogin: (login: LoginEntity) => void; } + // https://material-ui.com/styles/api/#makestyles-styles-options-hook @@ -478,14 +491,8 @@ interface PropsForm { + }) + ); -const LoginForm = (props: PropsForm) => { +export const LoginComponent: React.FC = (props) => { + const classes = useFormStyles(); - const { onLogin, onUpdateField, loginInfo } = props; - - // TODO: Enhacement move this outside the stateless component discuss why is a good idea - const onTexFieldChange = (fieldId) => (e) => { - onUpdateField(fieldId, e.target.value); - } return ( -
{ const [loginInfo, setLoginInfo] = React.useState( createEmptyLogin() ); -+ const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); ++ const [isShowAlert, setShowAlert] = React.useState(false); const classes = useStyles(); const onLogin = () => { @@ -602,7 +609,7 @@ const LoginPageInner = (props: Props) => { props.history.push("/pageB"); - } + } else { -+ setShowLoginFailedMsg(true); ++ setShowAlert(true); + } } @@ -625,11 +632,11 @@ const LoginPageInner = (props: Props) => { /> -+ setShowLoginFailedMsg(false)} -+ /> ++ setShowAlert(false)} ++ /> + ); }; diff --git a/hooks/13_LoginForm/src/pages/login.container.tsx b/hooks/13_LoginForm/src/pages/login.container.tsx index 0bf329ad..943c433b 100644 --- a/hooks/13_LoginForm/src/pages/login.container.tsx +++ b/hooks/13_LoginForm/src/pages/login.container.tsx @@ -47,7 +47,7 @@ export const LoginContainer: React.FC = (props) => { setShowAlert(false)} /> diff --git a/hooks/14_FormValidation/src/pages/login.container.tsx b/hooks/14_FormValidation/src/pages/login.container.tsx index 55d1f0c5..1da3ed87 100644 --- a/hooks/14_FormValidation/src/pages/login.container.tsx +++ b/hooks/14_FormValidation/src/pages/login.container.tsx @@ -48,7 +48,7 @@ export const LoginContainer: React.FC = (props) => { setShowAlert(false)} /> diff --git a/hooks/15_Context/src/pages/login.container.tsx b/hooks/15_Context/src/pages/login.container.tsx index 59574c3f..e3e65ca0 100644 --- a/hooks/15_Context/src/pages/login.container.tsx +++ b/hooks/15_Context/src/pages/login.container.tsx @@ -49,7 +49,7 @@ export const LoginContainer: React.FC = (props) => { setShowAlert(false)} /> From 21a0f2166aafd1c60ea32adde1b8b1400b5a9f18 Mon Sep 17 00:00:00 2001 From: Luis del Amo Date: Fri, 14 Aug 2020 12:08:40 +0200 Subject: [PATCH 37/37] ref:#187 doc 14 and 15 --- hooks/14_FormValidation/Readme.md | 213 ++++++++---------------------- hooks/15_Context/Readme.md | 48 +++---- 2 files changed, 72 insertions(+), 189 deletions(-) diff --git a/hooks/14_FormValidation/Readme.md b/hooks/14_FormValidation/Readme.md index d0b0b97a..f8538d50 100644 --- a/hooks/14_FormValidation/Readme.md +++ b/hooks/14_FormValidation/Readme.md @@ -28,47 +28,31 @@ npm install formik @lemoncode/fonk @lemoncode/fonk-formik --save - To avoid having too much repeated code let's move to common an input component, including it's label plus validation text. -_./common/textFieldForm.tsx_ +_./common/textField.component.tsx_ ```tsx import * as React from "react"; -import TextField from "@material-ui/core/TextField"; -import Typography from "@material-ui/core/Typography/Typography"; - -interface Props { - name: string; - label: string; - onChange: any; - value: string; - error?: string; - type?: string; -} - -const defaultProps: Partial = { - type: "text" -}; +import { useField } from "formik"; +import MuiTextField, { TextFieldProps } from "@material-ui/core/TextField"; -const onTextFieldChange = ( - fieldId: string, - onChange: (fieldId, value) => void -) => e => { - onChange(fieldId, e.target.value); -}; +export const TextFieldComponent: React.FC = (props) => { + const [field, meta] = useField(props.name); + const textFieldProps = Boolean(field) ? field : props; + const hasError = Boolean(meta && meta.touched && meta.error); -export const TextFieldForm: React.StatelessComponent = props => { - const { name, label, onChange, value, error, type } = props; return ( <> - - - {props.error} - ); }; @@ -80,12 +64,12 @@ _./src/common/index.ts_ ```diff export * from './notification'; -+ export * from './textFieldForm'; ++ export * from './TextFieldComponent'; ``` - Now let's define a basic validation for the form, we want to ensure both fields are informed. -_./src/pages/loginPage.validation.ts_ +_./src/pages/login.validation.ts_ ```typescript import { ValidationSchema, Validators } from "@lemoncode/fonk"; @@ -105,151 +89,62 @@ export const loginFormValidation = createFormikValidation(validationSchema); - First let's add the dataFormErrors to the state of the component. -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff import { isValidLogin } from "../api/login"; import { NotificationComponent } from "../common"; ``` -_./src/pages/loginPage.tsx_ - -```diff -const LoginPageInner = (props: Props) => { - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); -+ const [loginFormErrors, setLoginFormErrors] = React.useState(createDefaultLoginFormErrors()); - const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); -``` - -- Let's fire the validation on viewmodel update. - -_./src/pages/loginPage.tsx_ - -```diff -+ import { loginFormValidation } from "./loginPage.validation"; -``` - -_./src/pages/loginPage.tsx_ - -```diff -const onUpdateLoginField = (name, value) => { - setLoginInfo({ - ...loginInfo, - [name]: value - }); - -+ loginFormValidation.validateField(loginInfo, name, value) -+ .then((fieldValidationResult) => { - -+ setLoginFormErrors({ -+ ...loginFormErrors, -+ [name]: fieldValidationResult, -+ }); -+ }); - }; -``` - -- We need to pass down dataFormErrors - -_./src/pages/loginPage.tsx_ - -```diff - -``` - -_./src/pages/loginPage.tsx_ -```diff -interface PropsForm { - onLogin: () => void; - onUpdateField: (string, any) => void; - loginInfo: LoginEntity; -+ loginFormErrors : LoginFormErrors; -} -``` - -- Let's replace the _TextFieldForm_ entries with the wrapper we have created (includes +- Let's fire the validation on viewmodel update and replace the _TextFieldForm_ entries with the wrapper we have created (includes displaying validation errors). -_./src/pages/loginPage.tsx_ - -```diff -+ import { TextFieldForm } from '../common'; -``` - -_./src/pages/loginPage.tsx_ - -```diff -const LoginForm = (props: PropsForm) => { -- const { onLogin, onUpdateField, loginInfo } = props; -+ const { onLogin, onUpdateField, loginInfo, loginFormErrors } = props; -``` +_./src/pages/login.component.tsx_ ```diff -- -- ++ import { loginFormValidation } from "./login.validation"; ++ import { TextFieldComponent } from '../common'; + ++ ++ {() => ( ++
++
+- +- ++
++
++ )} ++
``` - Let's give a try -``` +```bash npm start ``` - And let's add an alert (Excercise and a notification) when the user clicks and the form all the fields are valid. -_./src/pages/loginPage.tsx_ - -```diff -const onLogin = () => { -+ loginFormValidation.validateForm(loginInfo) -+ .then((formValidationResult) => { -+ if(formValidationResult.succeeded) { - if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); - } else { - setShowLoginFailedMsg(true); - } -+ } else { -+ alert('error, review the fields'); -+ const updatedLoginFormErrors = { -+ ...loginFormErrors, -+ ...formValidationResult.fieldErrors, -+ } -+ setLoginFormErrors(updatedLoginFormErrors); -+ } - - -+ }); -}; -``` - > Excercise, refactor this method following single abstraction level principle and single responsibility principle. # About Basefactor + Lemoncode diff --git a/hooks/15_Context/Readme.md b/hooks/15_Context/Readme.md index 38ef6245..fb20ed96 100644 --- a/hooks/15_Context/Readme.md +++ b/hooks/15_Context/Readme.md @@ -119,7 +119,7 @@ import { Link } from "react-router-dom"; - Let's update the loginPage. -_./src/pages/loginPage.tsx_ +_./src/pages/login.container.tsx_ ```diff - import { TextFieldForm } from "../common"; @@ -130,37 +130,25 @@ _./src/pages/loginPage.tsx_ _./src/pages/loginPage.tsx_ ```diff -const LoginPageInner = (props: Props) => { -+ const loginContext = React.useContext(SessionContext); +export const LoginContainer: React.FC = (props) => { ++ const loginContext = React.useContext(SessionContext); + const history = useHistory(); + const [isShowAlert, setShowAlert] = React.useState(false); + const classes = useFormStyles(); + + const loginSucceeded = (isValid: boolean, login: LoginEntity) => { + if (isValid) { + history.push("/pageB"); ++ loginContext.updateLogin(login.login); + } else { + setShowAlert(true); + } + }; - const [loginInfo, setLoginInfo] = React.useState( - createEmptyLogin() - ); - const [loginFormErrors, setLoginFormErrors] = React.useState( - createDefaultLoginFormErrors() - ); - const [showLoginFailedMsg, setShowLoginFailedMsg] = React.useState(false); - const classes = useStyles(); - - const onLogin = () => { - loginFormValidation.validateForm(loginInfo).then(formValidationResult => { - if (formValidationResult.succeeded) { - if (isValidLogin(loginInfo)) { - props.history.push("/pageB"); -+ loginContext.updateLogin(loginInfo.login); - } else { - setShowLoginFailedMsg(true); - } - } else { - alert("error, review the fields"); - const updatedLoginFormErrors = { - ...loginFormErrors, - ...formValidationResult.fieldErrors - }; - setLoginFormErrors(updatedLoginFormErrors); - } - }); + const handleLogin = (login: LoginEntity) => { + isValidLogin(login).then((isValid) => loginSucceeded(isValid, login)); }; +}; ``` - Let's give a try.