├── 11-redux-firebase ├── src │ ├── App.css │ ├── index.css │ ├── types │ │ └── types.js │ ├── setupTests.js │ ├── App.test.js │ ├── reducers │ │ ├── authReducer.js │ │ └── nominaReducer.js │ ├── App.js │ ├── routers │ │ ├── PublicRouter.jsx │ │ ├── PrivateRouter.jsx │ │ ├── AuthRouter.jsx │ │ └── AppRouter.jsx │ ├── helpers │ │ └── loadData.js │ ├── reportWebVitals.js │ ├── index.js │ ├── store │ │ └── store.js │ ├── firebase │ │ └── config-firebase.js │ ├── components │ │ ├── Element.jsx │ │ ├── Navbar.jsx │ │ └── FormAdd.jsx │ ├── pages │ │ ├── AppScreen.jsx │ │ ├── LoginScreen.jsx │ │ └── RegisterScreen.jsx │ ├── actions │ │ ├── nomina.js │ │ └── auth.js │ ├── logo.svg │ ├── service-worker.js │ └── serviceWorkerRegistration.js ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── .gitignore └── package.json ├── .vscode └── settings.json ├── 04-hooks └── 04-hooks.zip ├── 08-router-v5 ├── assets.zip └── 08-router.zip ├── 09-router-v6 ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── assets │ │ ├── animate.gif │ │ ├── h-gohan.png │ │ ├── h-goku.png │ │ ├── m-bulma.png │ │ ├── m-gine.png │ │ ├── m-milk.png │ │ ├── m-no18.png │ │ ├── m-vados.png │ │ ├── m-videl.png │ │ ├── h-bardock.png │ │ ├── h-krillin.png │ │ ├── h-piccolo.png │ │ ├── h-vegeta.png │ │ ├── h-majin_buu.png │ │ └── m-caulifla.png │ ├── manifest.json │ └── index.html ├── src │ ├── types │ │ └── authTypes.js │ ├── context │ │ └── AuthContext.js │ ├── reducers │ │ └── AuthReducer.js │ ├── routes │ │ ├── PrivateRouter.jsx │ │ ├── PublicRouter.jsx │ │ ├── LoginRouter.jsx │ │ └── AppRouter.jsx │ ├── reportWebVitals.js │ ├── index.js │ ├── pages │ │ ├── ManScreen.jsx │ │ ├── WomanScreen.jsx │ │ ├── LoginScreen.jsx │ │ ├── CharacterScreen.jsx │ │ └── SearchScreen.jsx │ ├── App.js │ ├── components │ │ ├── Card.jsx │ │ └── Navbar.jsx │ ├── models │ │ └── Characters.js │ ├── service-worker.js │ └── serviceWorkerRegistration.js ├── .gitignore └── package.json ├── 06-reducer └── 06-reducer.zip ├── 03-detalles └── 03-detalles.zip ├── 01-react-cdn └── 01-react-cdn.zip ├── 00-nivelacion ├── 00-nivelacion.zip └── 00-miNivelación │ ├── js │ ├── ternario.js │ ├── functions.js │ └── variables.js │ └── index.html ├── 02-fundamentos └── 02-fundamentos.zip ├── 10-sass-react └── 09-sass-react.zip ├── 01-react-cdn-pwa └── 01-react-cdn-pwa.zip ├── 07-context-router └── 07-context-router.zip ├── 05-image-gallery-app └── 05-image-gallery-app.zip └── .gitignore /11-redux-firebase/src/App.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /11-redux-firebase/src/index.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /04-hooks/04-hooks.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/04-hooks/04-hooks.zip -------------------------------------------------------------------------------- /08-router-v5/assets.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/08-router-v5/assets.zip -------------------------------------------------------------------------------- /09-router-v6/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /06-reducer/06-reducer.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/06-reducer/06-reducer.zip -------------------------------------------------------------------------------- /11-redux-firebase/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /03-detalles/03-detalles.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/03-detalles/03-detalles.zip -------------------------------------------------------------------------------- /08-router-v5/08-router.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/08-router-v5/08-router.zip -------------------------------------------------------------------------------- /09-router-v6/src/types/authTypes.js: -------------------------------------------------------------------------------- 1 | export const authTypes = { 2 | login: "login", 3 | logout: "logout", 4 | }; 5 | -------------------------------------------------------------------------------- /01-react-cdn/01-react-cdn.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/01-react-cdn/01-react-cdn.zip -------------------------------------------------------------------------------- /00-nivelacion/00-nivelacion.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/00-nivelacion/00-nivelacion.zip -------------------------------------------------------------------------------- /02-fundamentos/02-fundamentos.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/02-fundamentos/02-fundamentos.zip -------------------------------------------------------------------------------- /09-router-v6/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/favicon.ico -------------------------------------------------------------------------------- /09-router-v6/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/logo192.png -------------------------------------------------------------------------------- /09-router-v6/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/logo512.png -------------------------------------------------------------------------------- /10-sass-react/09-sass-react.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/10-sass-react/09-sass-react.zip -------------------------------------------------------------------------------- /09-router-v6/src/context/AuthContext.js: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | export const AuthContext = createContext(); 4 | -------------------------------------------------------------------------------- /01-react-cdn-pwa/01-react-cdn-pwa.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/01-react-cdn-pwa/01-react-cdn-pwa.zip -------------------------------------------------------------------------------- /09-router-v6/public/assets/animate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/animate.gif -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-gohan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-gohan.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-goku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-goku.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-bulma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-bulma.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-gine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-gine.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-milk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-milk.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-no18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-no18.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-vados.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-vados.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-videl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-videl.png -------------------------------------------------------------------------------- /11-redux-firebase/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/11-redux-firebase/public/favicon.ico -------------------------------------------------------------------------------- /11-redux-firebase/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/11-redux-firebase/public/logo192.png -------------------------------------------------------------------------------- /11-redux-firebase/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/11-redux-firebase/public/logo512.png -------------------------------------------------------------------------------- /07-context-router/07-context-router.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/07-context-router/07-context-router.zip -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-bardock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-bardock.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-krillin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-krillin.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-piccolo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-piccolo.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-vegeta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-vegeta.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/h-majin_buu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/h-majin_buu.png -------------------------------------------------------------------------------- /09-router-v6/public/assets/m-caulifla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/09-router-v6/public/assets/m-caulifla.png -------------------------------------------------------------------------------- /05-image-gallery-app/05-image-gallery-app.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YirsisHertz/codigos-curso-react/HEAD/05-image-gallery-app/05-image-gallery-app.zip -------------------------------------------------------------------------------- /11-redux-firebase/src/types/types.js: -------------------------------------------------------------------------------- 1 | export const types = { 2 | login: "[Auth] login", 3 | logout: "[Auth] logout", 4 | 5 | nominaAdd: "[Nomina] add", 6 | nominaDelete: "[Nomina] delete", 7 | nominaRead: "[Nomina] read", 8 | nominaClean: "[Nomina] clean", 9 | }; 10 | -------------------------------------------------------------------------------- /11-redux-firebase/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /11-redux-firebase/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /11-redux-firebase/src/reducers/authReducer.js: -------------------------------------------------------------------------------- 1 | import { types } from "../types/types"; 2 | 3 | export const authReducer = (state = {}, action) => { 4 | switch (action.type) { 5 | case types.login: 6 | return action.payload; 7 | 8 | case types.logout: 9 | return {}; 10 | 11 | default: 12 | return state; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /09-router-v6/src/reducers/AuthReducer.js: -------------------------------------------------------------------------------- 1 | import { authTypes } from "../types/authTypes"; 2 | 3 | export const AuthReducer = (state, action) => { 4 | switch (action.type) { 5 | case authTypes.login: 6 | return { log: true }; 7 | 8 | case authTypes.logout: 9 | return { log: false }; 10 | 11 | default: 12 | return state; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /11-redux-firebase/src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Provider } from "react-redux"; 3 | 4 | import { store } from "./store/store"; 5 | 6 | import AppRouter from "./routers/AppRouter"; 7 | 8 | function App() { 9 | return ( 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /09-router-v6/src/routes/PrivateRouter.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Navigate } from "react-router"; 3 | 4 | import { AuthContext } from "../context/AuthContext"; 5 | 6 | const PrivateRouter = ({ children }) => { 7 | const { log } = useContext(AuthContext); 8 | 9 | return log.log ? children : ; 10 | }; 11 | 12 | export default PrivateRouter; 13 | -------------------------------------------------------------------------------- /09-router-v6/src/routes/PublicRouter.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Navigate } from "react-router"; 3 | 4 | import { AuthContext } from "../context/AuthContext"; 5 | 6 | const PublicRouter = ({ children }) => { 7 | const { log } = useContext(AuthContext); 8 | 9 | return !log.log ? children : ; 10 | }; 11 | 12 | export default PublicRouter; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | -------------------------------------------------------------------------------- /11-redux-firebase/src/routers/PublicRouter.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Redirect, Route } from "react-router"; 3 | 4 | const PublicRouter = ({ log, component: Component, ...resto }) => { 5 | return ( 6 | 9 | log ? : 10 | } 11 | /> 12 | ); 13 | }; 14 | 15 | export default PublicRouter; 16 | -------------------------------------------------------------------------------- /09-router-v6/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /11-redux-firebase/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /11-redux-firebase/src/routers/PrivateRouter.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Redirect, Route } from "react-router"; 3 | 4 | const PrivateRouter = ({ log, component: Component, ...resto }) => { 5 | return ( 6 | 9 | log ? : 10 | } 11 | /> 12 | ); 13 | }; 14 | 15 | export default PrivateRouter; 16 | -------------------------------------------------------------------------------- /09-router-v6/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /11-redux-firebase/src/helpers/loadData.js: -------------------------------------------------------------------------------- 1 | import { db } from "../firebase/config-firebase"; 2 | 3 | export const loadData = async (uid) => { 4 | const response = await db.collection(`${uid}/nominas/nomina`).get(); 5 | const data = []; 6 | 7 | response.forEach((nomina) => { 8 | const nominaData = nomina.data(); 9 | 10 | data.push({ 11 | id: nomina.id, 12 | ...nominaData, 13 | }); 14 | }); 15 | 16 | return data; 17 | }; 18 | -------------------------------------------------------------------------------- /11-redux-firebase/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /11-redux-firebase/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | 4 | import App from "./App"; 5 | 6 | import * as serviceWorkerRegistration from "./serviceWorkerRegistration"; 7 | import reportWebVitals from "./reportWebVitals"; 8 | 9 | ReactDOM.render( 10 | 11 | 12 | , 13 | document.getElementById("root") 14 | ); 15 | 16 | serviceWorkerRegistration.register(); 17 | 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /09-router-v6/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { hydrate, render } from "react-dom"; 3 | 4 | import App from "./App"; 5 | import * as serviceWorkerRegistration from "./serviceWorkerRegistration"; 6 | import reportWebVitals from "./reportWebVitals"; 7 | 8 | const root = document.getElementById("root"); 9 | 10 | if (root.hasChildNodes()) { 11 | hydrate(, root); 12 | } else { 13 | render(, root); 14 | } 15 | 16 | serviceWorkerRegistration.register(); 17 | 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /11-redux-firebase/src/routers/AuthRouter.jsx: -------------------------------------------------------------------------------- 1 | import { Redirect, Route, Switch } from "react-router-dom"; 2 | 3 | import LoginScreen from "../pages/LoginScreen"; 4 | import RegisterScreen from "../pages/RegisterScreen"; 5 | 6 | const AuthRouter = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default AuthRouter; 18 | -------------------------------------------------------------------------------- /09-router-v6/src/pages/ManScreen.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Card from "../components/Card"; 3 | import { Characters } from "../models/Characters"; 4 | 5 | const ManScreen = () => { 6 | const mans = Characters.filter((character) => character.type === "h"); 7 | 8 | return ( 9 |
10 |

Mans Screen

11 |
12 |
13 | {mans.map((man) => ( 14 | 15 | ))} 16 |
17 |
18 | ); 19 | }; 20 | 21 | export default ManScreen; 22 | -------------------------------------------------------------------------------- /09-router-v6/src/pages/WomanScreen.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Card from "../components/Card"; 3 | import { Characters } from "../models/Characters"; 4 | 5 | const WomanScreen = () => { 6 | const womans = Characters.filter((character) => character.type === "m"); 7 | 8 | return ( 9 |
10 |

Womans Screen

11 |
12 |
13 | {womans.map((woman) => ( 14 | 15 | ))} 16 |
17 |
18 | ); 19 | }; 20 | 21 | export default WomanScreen; 22 | -------------------------------------------------------------------------------- /00-nivelacion/00-miNivelación/js/ternario.js: -------------------------------------------------------------------------------- 1 | //Forma base 2 | const cuenta = 10; 3 | let mensaje; 4 | if (cuenta > 0) mensaje = "No tenes mas saldo raton"; 5 | else mensaje = "pagate el pancho chango"; 6 | 7 | console.write(mensaje); 8 | 9 | //Forma mejorada: Operador ternario 10 | const mensaje = 11 | cuenta < 0 ? "No tenes saldo chango" : "Pagate el pancho chango"; 12 | console.write(mensaje); 13 | 14 | //operador ternario de una sola 'verdad' 15 | const mensaje1; 16 | if(true) mensaje1 = "hola"; 17 | console.write(mensaje1) 18 | //Forma mejorada 19 | const mensaje2 = cuenta > 0&& "hola"; 20 | console.write(mensaje2); -------------------------------------------------------------------------------- /09-router-v6/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "DB App", 3 | "name": "DB App Router", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": "./", 22 | "display": "standalone", 23 | "theme_color": "#0dcaf0", 24 | "background_color": "#555555" 25 | } 26 | -------------------------------------------------------------------------------- /00-nivelacion/00-miNivelación/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Nivelacion 7 | 8 | 9 | 10 | 11 | 12 |

Hola Mundo

13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /11-redux-firebase/src/store/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, combineReducers, compose, applyMiddleware } from "redux"; 2 | import thunk from "redux-thunk"; 3 | 4 | import { authReducer } from "../reducers/authReducer"; 5 | import { nominaReducer } from "../reducers/nominaReducer"; 6 | 7 | const reducers = combineReducers({ 8 | auth: authReducer, 9 | nomina: nominaReducer, 10 | }); 11 | 12 | const composeEnhancers = 13 | (typeof window !== "undefined" && 14 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || 15 | compose; 16 | 17 | export const store = createStore( 18 | reducers, 19 | composeEnhancers(applyMiddleware(thunk)) 20 | ); 21 | -------------------------------------------------------------------------------- /11-redux-firebase/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Nominal App", 3 | "name": "Calculadora Nominal React + Redux + Firebase", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#3fe496", 24 | "background_color": "#088b83" 25 | } 26 | -------------------------------------------------------------------------------- /11-redux-firebase/src/firebase/config-firebase.js: -------------------------------------------------------------------------------- 1 | import firebase from "firebase/app"; 2 | import "firebase/firestore"; 3 | import "firebase/auth"; 4 | 5 | const firebaseConfig = { 6 | apiKey: "AIzaSyDbMB54QWwqqYJaGq4SswAeT5dk13en2Cs", 7 | authDomain: "crud-react-94987.firebaseapp.com", 8 | projectId: "crud-react-94987", 9 | storageBucket: "crud-react-94987.appspot.com", 10 | messagingSenderId: "746713242296", 11 | appId: "1:746713242296:web:5223ea9ee7d72fd589724d", 12 | }; 13 | 14 | // Initialize Firebase 15 | firebase.initializeApp(firebaseConfig); 16 | 17 | const db = firebase.firestore(); 18 | const googleAuthProvider = new firebase.auth.GoogleAuthProvider(); 19 | 20 | export { firebase, db, googleAuthProvider }; 21 | -------------------------------------------------------------------------------- /09-router-v6/src/App.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useReducer } from "react"; 2 | 3 | import LoginRouter from "./routes/LoginRouter"; 4 | 5 | import { AuthContext } from "./context/AuthContext"; 6 | import { AuthReducer } from "./reducers/AuthReducer"; 7 | 8 | const init = () => { 9 | return JSON.parse(localStorage.getItem("log")) || { log: false }; 10 | }; 11 | 12 | const App = () => { 13 | const [log, dispatch] = useReducer(AuthReducer, {}, init); 14 | 15 | useEffect(() => { 16 | localStorage.setItem("log", JSON.stringify(log)); 17 | }, [log]); 18 | 19 | return ( 20 | 21 | 22 | 23 | ); 24 | }; 25 | 26 | export default App; 27 | -------------------------------------------------------------------------------- /09-router-v6/src/components/Card.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | const Card = ({ name, type, id }) => { 5 | const path = `/assets/${type}-${id}.png`; 6 | 7 | return ( 8 |
14 | {id} 15 | 16 |
17 |

{name}

18 |

19 | 20 | Ver Más... 21 | 22 |

23 |
24 |
25 | ); 26 | }; 27 | 28 | export default Card; 29 | -------------------------------------------------------------------------------- /00-nivelacion/00-miNivelación/js/functions.js: -------------------------------------------------------------------------------- 1 | function sumar(a, b) { 2 | document.write(a + b); 3 | } 4 | sumar(5, 4); 5 | 6 | //Forma mejorada 7 | function sumar(a, b) { 8 | return a + b; 9 | } 10 | const resultado = sumar(5, 4); 11 | document.write(resultado); 12 | /*Aca podemos sufrir un ataque xs, donde se puede redefinir el codigo*/ 13 | //Forma mejorada 14 | const sumar = (a, b) => { 15 | /*Aca uso una FatArrow function, en una constante evitando asi ataques xs*/ 16 | return a + b; 17 | }; 18 | const resultado = sumar(5, 4); 19 | console.write(resultado); 20 | //Forma aun mas mejorada 21 | const sumar = (a, b) => a + b; 22 | /*Aca mejoramos la FarArrow, que debido a que solo contiene una instruccion, podemos ahorrarnos las llaves y el retun*/ 23 | const resultado = sumar(5, 4); 24 | console.write(resultado); 25 | -------------------------------------------------------------------------------- /00-nivelacion/00-miNivelación/js/variables.js: -------------------------------------------------------------------------------- 1 | // //Var, Let, const 2 | // //var: todo navegador lee primero los var, pero no la asignacion a posterior, ademas que es vulnerable a ser modificado 3 | // var nombre = "Fede"; 4 | // document.write(nombre); 5 | 6 | // saludo; 7 | // saludo(); 8 | // var saludo = function () { 9 | // document.write(`Hola ${nombre}`); 10 | // }; 11 | // /*Let y const: son dos variables que siguen el flujo de ejecucion */ 12 | // //let: evita la redefinicion de una misma variable, evitamos cualquier alcance a nivel de scope, no se puede inicializar hasta que haya sido definida, y se puede usar x cantidad de veces y ser modificada en toda la ejecucion 13 | // document.write(nombre); 14 | let nombre = "Fede"; 15 | document.write(nombre); 16 | // //const: crea una variable que no puede ser reasignado su variable 17 | -------------------------------------------------------------------------------- /09-router-v6/src/pages/LoginScreen.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { useNavigate } from "react-router"; 3 | import { AuthContext } from "../context/AuthContext"; 4 | import { authTypes } from "../types/authTypes"; 5 | 6 | const LoginScreen = () => { 7 | const { dispatch } = useContext(AuthContext); 8 | 9 | const navigate = useNavigate(); 10 | 11 | const handleLogin = () => { 12 | dispatch({ type: authTypes.login }); 13 | 14 | navigate("/"); 15 | }; 16 | 17 | return ( 18 |
19 | animacion 20 |

Login Screen

21 | 24 |
25 | ); 26 | }; 27 | 28 | export default LoginScreen; 29 | -------------------------------------------------------------------------------- /11-redux-firebase/src/reducers/nominaReducer.js: -------------------------------------------------------------------------------- 1 | import { types } from "../types/types"; 2 | 3 | const initialState = { 4 | data: [], 5 | }; 6 | 7 | export const nominaReducer = (state = initialState, action) => { 8 | switch (action.type) { 9 | case types.nominaAdd: 10 | return { 11 | ...state, 12 | data: [...state.data, action.payload], 13 | }; 14 | 15 | case types.nominaRead: 16 | return { 17 | ...state, 18 | data: action.payload, 19 | }; 20 | 21 | case types.nominaDelete: 22 | return { 23 | ...state, 24 | data: state.data.filter((nomina) => { 25 | return nomina.id !== action.payload; 26 | }), 27 | }; 28 | 29 | case types.nominaClean: 30 | return { 31 | ...state, 32 | data: [], 33 | }; 34 | 35 | default: 36 | return state; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /09-router-v6/src/routes/LoginRouter.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; 3 | 4 | import AppRouter from "./AppRouter"; 5 | import LoginScreen from "../pages/LoginScreen"; 6 | import PublicRouter from "./PublicRouter"; 7 | import PrivateRouter from "./PrivateRouter"; 8 | 9 | const LoginRouter = () => { 10 | return ( 11 | 12 | 13 | 17 | 18 | 19 | } 20 | /> 21 | 22 | 26 | 27 | 28 | } 29 | /> 30 | 31 | 32 | ); 33 | }; 34 | 35 | export default LoginRouter; 36 | -------------------------------------------------------------------------------- /11-redux-firebase/src/components/Element.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { borrarRegistro } from "../actions/nomina"; 4 | 5 | const Element = ({ data }) => { 6 | const { fecha, pago, id } = data; 7 | 8 | const dispatch = useDispatch(); 9 | 10 | let fechaFormato; 11 | 12 | if (fecha.seconds) { 13 | const date = fecha.toDate(); 14 | fechaFormato = date.toLocaleDateString(); 15 | } else { 16 | fechaFormato = fecha; 17 | } 18 | 19 | const handleDelete = () => { 20 | dispatch(borrarRegistro(id)); 21 | }; 22 | 23 | return ( 24 | <> 25 | {fechaFormato} 26 | ${pago} 27 | 28 | 31 | 32 | 33 | ); 34 | }; 35 | 36 | export default Element; 37 | -------------------------------------------------------------------------------- /11-redux-firebase/src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { logout } from "../actions/auth"; 4 | import { limpiar } from "../actions/nomina"; 5 | 6 | const Navbar = () => { 7 | const dispatch = useDispatch(); 8 | 9 | const handleLogout = () => { 10 | dispatch(limpiar()); 11 | dispatch(logout()); 12 | }; 13 | 14 | return ( 15 | 30 | ); 31 | }; 32 | 33 | export default Navbar; 34 | -------------------------------------------------------------------------------- /09-router-v6/src/routes/AppRouter.jsx: -------------------------------------------------------------------------------- 1 | import React, { lazy, Suspense } from "react"; 2 | import { Route, Navigate, Routes } from "react-router-dom"; 3 | 4 | import Navbar from "../components/Navbar"; 5 | 6 | const CharacterScreen = lazy(() => import("../pages/CharacterScreen")); 7 | const ManScreen = lazy(() => import("../pages/ManScreen")); 8 | const SearchScreen = lazy(() => import("../pages/SearchScreen")); 9 | const WomanScreen = lazy(() => import("../pages/WomanScreen")); 10 | 11 | const AppRouter = () => { 12 | return ( 13 | <> 14 | 15 | Loading...}> 16 | 17 | } /> 18 | } /> 19 | } /> 20 | 21 | } /> 22 | 23 | } /> 24 | 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default AppRouter; 31 | -------------------------------------------------------------------------------- /09-router-v6/src/pages/CharacterScreen.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useParams, useNavigate } from "react-router-dom"; 3 | import { Characters } from "../models/Characters"; 4 | 5 | const CharacterScreen = () => { 6 | const { id } = useParams(); 7 | 8 | const navigate = useNavigate(); 9 | 10 | const { type, name, description } = Characters.find( 11 | (character) => character.id === id 12 | ); 13 | 14 | const path = `/assets/${type}-${id}.png`; 15 | 16 | const handleBack = () => { 17 | navigate(-1); 18 | }; 19 | 20 | return ( 21 |
22 |
23 | {id} 32 |
33 |
34 |

Nombre: {name}

35 |

Desccripción: {description}

36 | 37 | 40 |
41 |
42 | ); 43 | }; 44 | 45 | export default CharacterScreen; 46 | -------------------------------------------------------------------------------- /09-router-v6/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | Router App 17 | 18 | 24 | 25 | 30 | 31 | 32 | 33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /11-redux-firebase/src/pages/AppScreen.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useSelector } from "react-redux"; 3 | import Element from "../components/Element"; 4 | import FormAdd from "../components/FormAdd"; 5 | 6 | import Navbar from "../components/Navbar"; 7 | 8 | const AppScreen = () => { 9 | const name = useSelector((state) => state.auth.displayName); 10 | 11 | const data = useSelector((state) => state.nomina.data); 12 | 13 | return ( 14 | <> 15 | 16 | 17 |
18 |

Hola {name}

19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | {data.map((elemento) => { 34 | return ( 35 | 39 | 40 | 41 | ); 42 | })} 43 | 44 |
FechaCantidadBorrar
45 |
46 | 47 | ); 48 | }; 49 | 50 | export default AppScreen; 51 | -------------------------------------------------------------------------------- /11-redux-firebase/src/actions/nomina.js: -------------------------------------------------------------------------------- 1 | import { db } from "../firebase/config-firebase"; 2 | import { types } from "../types/types"; 3 | 4 | export const crearRegistro = (pago) => { 5 | return async (dispatch, getState) => { 6 | const { uid } = getState().auth; 7 | 8 | const datos = { 9 | fecha: new Date().toLocaleDateString(), 10 | pago, 11 | }; 12 | 13 | const referencia = await db.collection(`${uid}/nominas/nomina`).add(datos); 14 | 15 | const id = await referencia.id; 16 | 17 | const newData = { 18 | ...datos, 19 | id, 20 | }; 21 | 22 | dispatch(crear(newData)); 23 | }; 24 | }; 25 | 26 | export const leerRegistros = (data) => { 27 | return { 28 | type: types.nominaRead, 29 | payload: data, 30 | }; 31 | }; 32 | 33 | export const crear = (data) => { 34 | return { 35 | type: types.nominaAdd, 36 | payload: data, 37 | }; 38 | }; 39 | 40 | export const borrarRegistro = (id) => { 41 | return async (dispatch, getState) => { 42 | const { uid } = getState().auth; 43 | 44 | await db.doc(`${uid}/nominas/nomina/${id}`).delete(); 45 | 46 | dispatch(borrar(id)); 47 | }; 48 | }; 49 | 50 | export const borrar = (id) => { 51 | return { 52 | type: types.nominaDelete, 53 | payload: id, 54 | }; 55 | }; 56 | 57 | export const limpiar = () => { 58 | return { 59 | type: types.nominaClean, 60 | }; 61 | }; 62 | -------------------------------------------------------------------------------- /11-redux-firebase/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 29 | 30 | 34 | 35 | Calculadora Nominal 36 | 37 | 38 | 39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /11-redux-firebase/src/routers/AppRouter.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Switch } from "react-router-dom"; 3 | import { useEffect, useState } from "react"; 4 | import { useDispatch } from "react-redux"; 5 | 6 | import AppScreen from "../pages/AppScreen"; 7 | import AuthRouter from "./AuthRouter"; 8 | import PrivateRouter from "./PrivateRouter"; 9 | 10 | import { login } from "../actions/auth"; 11 | import { firebase } from "../firebase/config-firebase"; 12 | import PublicRouter from "./PublicRouter"; 13 | import { loadData } from "../helpers/loadData"; 14 | import { leerRegistros } from "../actions/nomina"; 15 | 16 | const AppRouter = () => { 17 | const dispatch = useDispatch(); 18 | 19 | const [log, setLog] = useState(false); 20 | 21 | useEffect(() => { 22 | firebase.auth().onAuthStateChanged(async (user) => { 23 | if (user) { 24 | dispatch(login(user.uid, user.displayName)); 25 | setLog(true); 26 | 27 | const nominaData = await loadData(user.uid); 28 | 29 | dispatch(leerRegistros(nominaData)); 30 | } else { 31 | setLog(false); 32 | } 33 | }); 34 | }, [dispatch]); 35 | 36 | return ( 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | }; 45 | 46 | export default AppRouter; 47 | -------------------------------------------------------------------------------- /11-redux-firebase/src/actions/auth.js: -------------------------------------------------------------------------------- 1 | import { types } from "../types/types"; 2 | 3 | import { firebase, googleAuthProvider } from "../firebase/config-firebase"; 4 | 5 | export const googleLogin = () => { 6 | return (dispatch) => { 7 | firebase 8 | .auth() 9 | .signInWithPopup(googleAuthProvider) 10 | .then(({ user }) => { 11 | dispatch(login(user.uid, user.displayName)); 12 | }); 13 | }; 14 | }; 15 | 16 | export const emailAndPasswordLogin = (email, password) => { 17 | return (dispatch) => { 18 | firebase 19 | .auth() 20 | .signInWithEmailAndPassword(email, password) 21 | .then(({ user }) => { 22 | dispatch(login(user.uid, user.displayName)); 23 | }); 24 | }; 25 | }; 26 | 27 | export const register = (email, password, username) => { 28 | return (dispatch) => { 29 | firebase 30 | .auth() 31 | .createUserWithEmailAndPassword(email, password) 32 | .then(async ({ user }) => { 33 | await user.updateProfile({ displayName: username }); 34 | 35 | dispatch(login(user.uid, user.displayName)); 36 | }); 37 | }; 38 | }; 39 | 40 | export const login = (uid, displayName) => { 41 | return { 42 | type: types.login, 43 | payload: { 44 | uid, 45 | displayName, 46 | }, 47 | }; 48 | }; 49 | 50 | export const logout = () => { 51 | return async (dispatch) => { 52 | await firebase.auth().signOut(); 53 | 54 | dispatch({ 55 | type: types.logout, 56 | }); 57 | }; 58 | }; 59 | -------------------------------------------------------------------------------- /09-router-v6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "08-router", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^12.1.2", 8 | "@testing-library/user-event": "^13.5.0", 9 | "query-string": "^7.0.0", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-router-dom": "^6.2.1", 13 | "react-scripts": "5.0.0", 14 | "web-vitals": "^2.1.2", 15 | "workbox-background-sync": "^6.4.2", 16 | "workbox-broadcast-update": "^6.4.2", 17 | "workbox-cacheable-response": "^6.4.2", 18 | "workbox-core": "^6.4.2", 19 | "workbox-expiration": "^6.4.2", 20 | "workbox-google-analytics": "^6.4.2", 21 | "workbox-navigation-preload": "^6.4.2", 22 | "workbox-precaching": "^6.4.2", 23 | "workbox-range-requests": "^6.4.2", 24 | "workbox-routing": "^6.4.2", 25 | "workbox-strategies": "^6.4.2", 26 | "workbox-streams": "^6.4.2" 27 | }, 28 | "scripts": { 29 | "start": "react-scripts start", 30 | "build": "react-scripts build", 31 | "postbuild": "react-snap", 32 | "test": "react-scripts test", 33 | "eject": "react-scripts eject" 34 | }, 35 | "eslintConfig": { 36 | "extends": [ 37 | "react-app", 38 | "react-app/jest" 39 | ] 40 | }, 41 | "browserslist": { 42 | "production": [ 43 | ">0.2%", 44 | "not dead", 45 | "not op_mini all" 46 | ], 47 | "development": [ 48 | "last 1 chrome version", 49 | "last 1 firefox version", 50 | "last 1 safari version" 51 | ] 52 | }, 53 | "devDependencies": { 54 | "react-snap": "^1.23.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /11-redux-firebase/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "10-redux-firebase", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "firebase": "^8.4.3", 10 | "react": "^17.0.2", 11 | "react-dom": "^17.0.2", 12 | "react-google-button": "^0.7.2", 13 | "react-redux": "^7.2.4", 14 | "react-router-dom": "^5.2.0", 15 | "react-scripts": "4.0.3", 16 | "redux": "^4.1.0", 17 | "redux-thunk": "^2.3.0", 18 | "web-vitals": "^0.2.4", 19 | "workbox-background-sync": "^5.1.3", 20 | "workbox-broadcast-update": "^5.1.3", 21 | "workbox-cacheable-response": "^5.1.3", 22 | "workbox-core": "^5.1.3", 23 | "workbox-expiration": "^5.1.3", 24 | "workbox-google-analytics": "^5.1.3", 25 | "workbox-navigation-preload": "^5.1.3", 26 | "workbox-precaching": "^5.1.3", 27 | "workbox-range-requests": "^5.1.3", 28 | "workbox-routing": "^5.1.3", 29 | "workbox-strategies": "^5.1.3", 30 | "workbox-streams": "^5.1.3" 31 | }, 32 | "scripts": { 33 | "start": "react-scripts start", 34 | "build": "react-scripts build", 35 | "test": "react-scripts test", 36 | "eject": "react-scripts eject" 37 | }, 38 | "eslintConfig": { 39 | "extends": [ 40 | "react-app", 41 | "react-app/jest" 42 | ] 43 | }, 44 | "browserslist": { 45 | "production": [ 46 | ">0.2%", 47 | "not dead", 48 | "not op_mini all" 49 | ], 50 | "development": [ 51 | "last 1 chrome version", 52 | "last 1 firefox version", 53 | "last 1 safari version" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /09-router-v6/src/models/Characters.js: -------------------------------------------------------------------------------- 1 | export const Characters = [ 2 | { 3 | id: "bardock", 4 | name: "Bardock", 5 | description: "Papá de Goku", 6 | type: "h", 7 | }, 8 | { 9 | id: "gohan", 10 | name: "Gohan", 11 | description: "Hijo mayor de Goku", 12 | type: "h", 13 | }, 14 | { 15 | id: "goku", 16 | name: "Goku", 17 | description: "Protagonista de DB", 18 | type: "h", 19 | }, 20 | { 21 | id: "krillin", 22 | name: "Krillin", 23 | description: "Mejor amigo de Goku", 24 | type: "h", 25 | }, 26 | { 27 | id: "majin_buu", 28 | name: "Majin Buu", 29 | description: "Enemigo en la saga de Buu en DB Z", 30 | type: "h", 31 | }, 32 | 33 | { 34 | id: "piccolo", 35 | name: "Piccolo", 36 | description: "Enemigo y despues amigo de Goku", 37 | type: "h", 38 | }, 39 | { 40 | id: "vegeta", 41 | name: "Vegeta", 42 | description: "Principe de los Saiyajin", 43 | type: "h", 44 | }, 45 | { 46 | id: "bulma", 47 | name: "Bulma", 48 | description: "Esposa de Vegeta", 49 | type: "m", 50 | }, 51 | { 52 | id: "caulifla", 53 | name: "Caulifla", 54 | description: "Saiyajin de otro universo", 55 | type: "m", 56 | }, 57 | { 58 | id: "gine", 59 | name: "Gine", 60 | description: "Mamá de Goku", 61 | type: "m", 62 | }, 63 | { 64 | id: "milk", 65 | name: "Milk", 66 | description: "Esposa de Goku", 67 | type: "m", 68 | }, 69 | { 70 | id: "no18", 71 | name: "Androide No. 18", 72 | description: "Esposa de Krillin", 73 | type: "m", 74 | }, 75 | { 76 | id: "vados", 77 | name: "Vados", 78 | description: "Angel del dios de la destruccion Champa", 79 | type: "m", 80 | }, 81 | { 82 | id: "videl", 83 | name: "Videl", 84 | description: "Esposa de Gohan", 85 | type: "m", 86 | }, 87 | ]; 88 | -------------------------------------------------------------------------------- /11-redux-firebase/src/components/FormAdd.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { crearRegistro } from "../actions/nomina"; 4 | 5 | const FormAdd = () => { 6 | const dispatch = useDispatch(); 7 | const [viewForm, setViewForm] = useState(false); 8 | 9 | const [cantidadPago, setCantidadPago] = useState({ 10 | precioHora: 0, 11 | horas: 0, 12 | }); 13 | 14 | const { precioHora, horas } = cantidadPago; 15 | 16 | const handleAdd = () => { 17 | setViewForm(!viewForm); 18 | }; 19 | 20 | const handleChange = (e) => { 21 | setCantidadPago({ 22 | ...cantidadPago, 23 | [e.target.name]: e.target.value, 24 | }); 25 | }; 26 | 27 | const handleSave = () => { 28 | const cantidadFinal = horas * precioHora; 29 | 30 | dispatch(crearRegistro(cantidadFinal)); 31 | 32 | setCantidadPago({ 33 | precioHora: 0, 34 | horas: 0, 35 | }); 36 | }; 37 | 38 | return ( 39 |
40 | 43 | {viewForm && ( 44 |
45 |
46 | 47 | 54 |
55 | 56 |
57 | 58 | 65 |
66 | 69 |
70 | )} 71 |
72 | ); 73 | }; 74 | 75 | export default FormAdd; 76 | -------------------------------------------------------------------------------- /09-router-v6/src/pages/SearchScreen.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useLocation, useNavigate } from "react-router-dom"; 3 | import queryString from "query-string"; 4 | import { Characters } from "../models/Characters"; 5 | import Card from "../components/Card"; 6 | 7 | const SearchScreen = () => { 8 | const location = useLocation(); 9 | const navigate = useNavigate(); 10 | 11 | const { q = "" } = queryString.parse(location.search); 12 | 13 | const [inputValue, setInputValue] = useState(q); 14 | const [characters, setCharacters] = useState([]); 15 | 16 | const handleChange = (e) => { 17 | const value = e.target.value; 18 | setInputValue(value); 19 | }; 20 | 21 | const handleSubmit = (e) => { 22 | e.preventDefault(); 23 | navigate(`?q=${inputValue}`); 24 | }; 25 | 26 | const getCharacters = () => { 27 | if (inputValue.trim() !== "") { 28 | const value = inputValue.toLocaleLowerCase(); 29 | const newValue = Characters.filter((character) => 30 | character.name.toLocaleLowerCase().includes(value) 31 | ); 32 | 33 | setCharacters(newValue); 34 | } else { 35 | setCharacters([]); 36 | } 37 | }; 38 | 39 | useEffect(() => { 40 | getCharacters(); 41 | }, [q]); 42 | 43 | return ( 44 |
45 |

Search Screen

46 |
47 |
48 |
49 |

Search

50 |
51 | 62 | 65 |
66 |
67 |
68 |

Results: {characters.length}

69 | {characters.length === 0 && ( 70 |
71 | Please Search a Character 72 |
73 | )} 74 | 75 | {characters.map((character) => ( 76 | 77 | ))} 78 |
79 |
80 |
81 | ); 82 | }; 83 | 84 | export default SearchScreen; 85 | -------------------------------------------------------------------------------- /11-redux-firebase/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /09-router-v6/src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { NavLink, useNavigate } from "react-router-dom"; 3 | import { AuthContext } from "../context/AuthContext"; 4 | import { authTypes } from "../types/authTypes"; 5 | 6 | const Navbar = () => { 7 | const navigate = useNavigate(); 8 | 9 | const { dispatch } = useContext(AuthContext); 10 | 11 | const handleLogout = () => { 12 | dispatch({ type: authTypes.logout }); 13 | 14 | navigate("/login"); 15 | }; 16 | 17 | return ( 18 | 76 | ); 77 | }; 78 | 79 | export default Navbar; 80 | -------------------------------------------------------------------------------- /11-redux-firebase/src/pages/LoginScreen.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | 4 | import GoogleButton from "react-google-button"; 5 | import { Link } from "react-router-dom"; 6 | 7 | import { googleLogin, emailAndPasswordLogin } from "../actions/auth"; 8 | 9 | const LoginScreen = () => { 10 | const [data, setData] = useState({ 11 | email: "", 12 | password: "", 13 | }); 14 | 15 | const { email, password } = data; 16 | 17 | const handleChange = (e) => { 18 | const value = e.target.value; 19 | 20 | setData({ 21 | ...data, 22 | [e.target.name]: value, 23 | }); 24 | }; 25 | 26 | const dispatch = useDispatch(); 27 | 28 | const handleGoogleLogin = () => { 29 | dispatch(googleLogin()); 30 | }; 31 | 32 | const handleEmailLogin = (e) => { 33 | e.preventDefault(); 34 | 35 | if (email.trim() === "" || !email.trim().includes("@")) { 36 | return; 37 | } 38 | 39 | if (password.trim().length < 6) { 40 | return; 41 | } 42 | 43 | dispatch(emailAndPasswordLogin(email, password)); 44 | }; 45 | 46 | return ( 47 |
48 |

Login

49 |
50 | 51 |
52 |
53 |
54 |
55 | email 56 | 64 | 65 |
66 |
67 | vpn_key 68 | 76 | 77 |
78 |
79 | 80 | 83 |
84 | 85 | Register in the platform 86 | 87 |
88 |
89 | ); 90 | }; 91 | 92 | export default LoginScreen; 93 | -------------------------------------------------------------------------------- /09-router-v6/src/service-worker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | 3 | // This service worker can be customized! 4 | // See https://developers.google.com/web/tools/workbox/modules 5 | // for the list of available Workbox modules, or add any other 6 | // code you'd like. 7 | // You can also remove this file if you'd prefer not to use a 8 | // service worker, and the Workbox build step will be skipped. 9 | 10 | import { clientsClaim } from 'workbox-core'; 11 | import { ExpirationPlugin } from 'workbox-expiration'; 12 | import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; 13 | import { registerRoute } from 'workbox-routing'; 14 | import { StaleWhileRevalidate } from 'workbox-strategies'; 15 | 16 | clientsClaim(); 17 | 18 | // Precache all of the assets generated by your build process. 19 | // Their URLs are injected into the manifest variable below. 20 | // This variable must be present somewhere in your service worker file, 21 | // even if you decide not to use precaching. See https://cra.link/PWA 22 | precacheAndRoute(self.__WB_MANIFEST); 23 | 24 | // Set up App Shell-style routing, so that all navigation requests 25 | // are fulfilled with your index.html shell. Learn more at 26 | // https://developers.google.com/web/fundamentals/architecture/app-shell 27 | const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); 28 | registerRoute( 29 | // Return false to exempt requests from being fulfilled by index.html. 30 | ({ request, url }) => { 31 | // If this isn't a navigation, skip. 32 | if (request.mode !== 'navigate') { 33 | return false; 34 | } // If this is a URL that starts with /_, skip. 35 | 36 | if (url.pathname.startsWith('/_')) { 37 | return false; 38 | } // If this looks like a URL for a resource, because it contains // a file extension, skip. 39 | 40 | if (url.pathname.match(fileExtensionRegexp)) { 41 | return false; 42 | } // Return true to signal that we want to use the handler. 43 | 44 | return true; 45 | }, 46 | createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') 47 | ); 48 | 49 | // An example runtime caching route for requests that aren't handled by the 50 | // precache, in this case same-origin .png requests like those from in public/ 51 | registerRoute( 52 | // Add in any other file extensions or routing criteria as needed. 53 | ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst. 54 | new StaleWhileRevalidate({ 55 | cacheName: 'images', 56 | plugins: [ 57 | // Ensure that once this runtime cache reaches a maximum size the 58 | // least-recently used images are removed. 59 | new ExpirationPlugin({ maxEntries: 50 }), 60 | ], 61 | }) 62 | ); 63 | 64 | // This allows the web app to trigger skipWaiting via 65 | // registration.waiting.postMessage({type: 'SKIP_WAITING'}) 66 | self.addEventListener('message', (event) => { 67 | if (event.data && event.data.type === 'SKIP_WAITING') { 68 | self.skipWaiting(); 69 | } 70 | }); 71 | 72 | // Any other custom service worker logic can go here. 73 | -------------------------------------------------------------------------------- /11-redux-firebase/src/service-worker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-restricted-globals */ 2 | 3 | // This service worker can be customized! 4 | // See https://developers.google.com/web/tools/workbox/modules 5 | // for the list of available Workbox modules, or add any other 6 | // code you'd like. 7 | // You can also remove this file if you'd prefer not to use a 8 | // service worker, and the Workbox build step will be skipped. 9 | 10 | import { clientsClaim } from 'workbox-core'; 11 | import { ExpirationPlugin } from 'workbox-expiration'; 12 | import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; 13 | import { registerRoute } from 'workbox-routing'; 14 | import { StaleWhileRevalidate } from 'workbox-strategies'; 15 | 16 | clientsClaim(); 17 | 18 | // Precache all of the assets generated by your build process. 19 | // Their URLs are injected into the manifest variable below. 20 | // This variable must be present somewhere in your service worker file, 21 | // even if you decide not to use precaching. See https://cra.link/PWA 22 | precacheAndRoute(self.__WB_MANIFEST); 23 | 24 | // Set up App Shell-style routing, so that all navigation requests 25 | // are fulfilled with your index.html shell. Learn more at 26 | // https://developers.google.com/web/fundamentals/architecture/app-shell 27 | const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); 28 | registerRoute( 29 | // Return false to exempt requests from being fulfilled by index.html. 30 | ({ request, url }) => { 31 | // If this isn't a navigation, skip. 32 | if (request.mode !== 'navigate') { 33 | return false; 34 | } // If this is a URL that starts with /_, skip. 35 | 36 | if (url.pathname.startsWith('/_')) { 37 | return false; 38 | } // If this looks like a URL for a resource, because it contains // a file extension, skip. 39 | 40 | if (url.pathname.match(fileExtensionRegexp)) { 41 | return false; 42 | } // Return true to signal that we want to use the handler. 43 | 44 | return true; 45 | }, 46 | createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') 47 | ); 48 | 49 | // An example runtime caching route for requests that aren't handled by the 50 | // precache, in this case same-origin .png requests like those from in public/ 51 | registerRoute( 52 | // Add in any other file extensions or routing criteria as needed. 53 | ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst. 54 | new StaleWhileRevalidate({ 55 | cacheName: 'images', 56 | plugins: [ 57 | // Ensure that once this runtime cache reaches a maximum size the 58 | // least-recently used images are removed. 59 | new ExpirationPlugin({ maxEntries: 50 }), 60 | ], 61 | }) 62 | ); 63 | 64 | // This allows the web app to trigger skipWaiting via 65 | // registration.waiting.postMessage({type: 'SKIP_WAITING'}) 66 | self.addEventListener('message', (event) => { 67 | if (event.data && event.data.type === 'SKIP_WAITING') { 68 | self.skipWaiting(); 69 | } 70 | }); 71 | 72 | // Any other custom service worker logic can go here. 73 | -------------------------------------------------------------------------------- /11-redux-firebase/src/pages/RegisterScreen.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { Link } from "react-router-dom"; 4 | 5 | import { register } from "../actions/auth"; 6 | 7 | const RegisterScreen = () => { 8 | const dispatch = useDispatch(); 9 | 10 | const [data, setData] = useState({ 11 | email: "", 12 | password: "", 13 | password2: "", 14 | username: "", 15 | }); 16 | 17 | const { email, username, password, password2 } = data; 18 | 19 | const handleChange = (e) => { 20 | const value = e.target.value; 21 | 22 | setData({ 23 | ...data, 24 | [e.target.name]: value, 25 | }); 26 | }; 27 | 28 | const handleRegister = (e) => { 29 | e.preventDefault(); 30 | 31 | if (email.trim() === "" || !email.trim().includes("@")) { 32 | return; 33 | } 34 | 35 | if (username.trim().length < 2) { 36 | return; 37 | } 38 | 39 | if (password.trim().length < 6) { 40 | return; 41 | } else { 42 | if (password.trim() !== password2.trim()) { 43 | return; 44 | } 45 | } 46 | 47 | dispatch(register(email, password, username)); 48 | }; 49 | 50 | return ( 51 |
52 |

Register

53 |
54 | 55 |
56 |
57 |
58 |
59 | email 60 | 68 | 69 |
70 |
71 | assignment_ind 72 | 80 | 81 |
82 |
83 | vpn_key 84 | 92 | 93 |
94 |
95 | vpn_key 96 | 104 | 105 |
106 |
107 | 108 | 111 |
112 | Login into account 113 |
114 |
115 |
116 | ); 117 | }; 118 | 119 | export default RegisterScreen; 120 | -------------------------------------------------------------------------------- /09-router-v6/src/serviceWorkerRegistration.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://cra.link/PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) 19 | ); 20 | 21 | export function register(config) { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Let's check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl, config); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://cra.link/PWA' 45 | ); 46 | }); 47 | } else { 48 | // Is not localhost. Just register service worker 49 | registerValidSW(swUrl, config); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl, config) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then((registration) => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | if (installingWorker == null) { 62 | return; 63 | } 64 | installingWorker.onstatechange = () => { 65 | if (installingWorker.state === 'installed') { 66 | if (navigator.serviceWorker.controller) { 67 | // At this point, the updated precached content has been fetched, 68 | // but the previous service worker will still serve the older 69 | // content until all client tabs are closed. 70 | console.log( 71 | 'New content is available and will be used when all ' + 72 | 'tabs for this page are closed. See https://cra.link/PWA.' 73 | ); 74 | 75 | // Execute callback 76 | if (config && config.onUpdate) { 77 | config.onUpdate(registration); 78 | } 79 | } else { 80 | // At this point, everything has been precached. 81 | // It's the perfect time to display a 82 | // "Content is cached for offline use." message. 83 | console.log('Content is cached for offline use.'); 84 | 85 | // Execute callback 86 | if (config && config.onSuccess) { 87 | config.onSuccess(registration); 88 | } 89 | } 90 | } 91 | }; 92 | }; 93 | }) 94 | .catch((error) => { 95 | console.error('Error during service worker registration:', error); 96 | }); 97 | } 98 | 99 | function checkValidServiceWorker(swUrl, config) { 100 | // Check if the service worker can be found. If it can't reload the page. 101 | fetch(swUrl, { 102 | headers: { 'Service-Worker': 'script' }, 103 | }) 104 | .then((response) => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then((registration) => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log('No internet connection found. App is running in offline mode.'); 124 | }); 125 | } 126 | 127 | export function unregister() { 128 | if ('serviceWorker' in navigator) { 129 | navigator.serviceWorker.ready 130 | .then((registration) => { 131 | registration.unregister(); 132 | }) 133 | .catch((error) => { 134 | console.error(error.message); 135 | }); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /11-redux-firebase/src/serviceWorkerRegistration.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://cra.link/PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) 19 | ); 20 | 21 | export function register(config) { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Let's check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl, config); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://cra.link/PWA' 45 | ); 46 | }); 47 | } else { 48 | // Is not localhost. Just register service worker 49 | registerValidSW(swUrl, config); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl, config) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then((registration) => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | if (installingWorker == null) { 62 | return; 63 | } 64 | installingWorker.onstatechange = () => { 65 | if (installingWorker.state === 'installed') { 66 | if (navigator.serviceWorker.controller) { 67 | // At this point, the updated precached content has been fetched, 68 | // but the previous service worker will still serve the older 69 | // content until all client tabs are closed. 70 | console.log( 71 | 'New content is available and will be used when all ' + 72 | 'tabs for this page are closed. See https://cra.link/PWA.' 73 | ); 74 | 75 | // Execute callback 76 | if (config && config.onUpdate) { 77 | config.onUpdate(registration); 78 | } 79 | } else { 80 | // At this point, everything has been precached. 81 | // It's the perfect time to display a 82 | // "Content is cached for offline use." message. 83 | console.log('Content is cached for offline use.'); 84 | 85 | // Execute callback 86 | if (config && config.onSuccess) { 87 | config.onSuccess(registration); 88 | } 89 | } 90 | } 91 | }; 92 | }; 93 | }) 94 | .catch((error) => { 95 | console.error('Error during service worker registration:', error); 96 | }); 97 | } 98 | 99 | function checkValidServiceWorker(swUrl, config) { 100 | // Check if the service worker can be found. If it can't reload the page. 101 | fetch(swUrl, { 102 | headers: { 'Service-Worker': 'script' }, 103 | }) 104 | .then((response) => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then((registration) => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log('No internet connection found. App is running in offline mode.'); 124 | }); 125 | } 126 | 127 | export function unregister() { 128 | if ('serviceWorker' in navigator) { 129 | navigator.serviceWorker.ready 130 | .then((registration) => { 131 | registration.unregister(); 132 | }) 133 | .catch((error) => { 134 | console.error(error.message); 135 | }); 136 | } 137 | } 138 | --------------------------------------------------------------------------------