├── .DS_Store ├── README.md ├── exercicios_react ├── .gitignore ├── ex.1 │ └── index.jsx ├── ex.10 │ ├── family.jsx │ ├── index.jsx │ └── member.jsx ├── ex.11 │ ├── family.jsx │ ├── index.jsx │ └── member.jsx ├── ex.12 │ ├── family.jsx │ ├── index.jsx │ └── member.jsx ├── ex.13 │ ├── family.jsx │ ├── index.jsx │ └── member.jsx ├── ex.14 │ ├── family.jsx │ ├── index.jsx │ └── member.jsx ├── ex.15 │ ├── classComponent.jsx │ └── index.jsx ├── ex.16 │ ├── classComponent.jsx │ └── index.jsx ├── ex.17 │ ├── field.jsx │ └── index.jsx ├── ex.18 │ ├── field.jsx │ └── index.jsx ├── ex.19 │ ├── field.jsx │ ├── fieldActions.js │ ├── fieldReducer.js │ └── index.jsx ├── ex.2 │ ├── component.jsx │ └── index.jsx ├── ex.20 │ ├── counter.jsx │ ├── counterActions.js │ ├── counterReducer.js │ └── index.jsx ├── ex.3 │ ├── component.jsx │ └── index.jsx ├── ex.4 │ ├── component.jsx │ └── index.jsx ├── ex.5 │ ├── component.jsx │ └── index.jsx ├── ex.6 │ ├── component.jsx │ └── index.jsx ├── ex.7 │ ├── component.jsx │ └── index.jsx ├── ex.8 │ ├── component.jsx │ └── index.jsx ├── ex.9 │ ├── index.jsx │ ├── member.jsx │ └── silvaFamily.jsx ├── ex │ ├── counter.jsx │ ├── counterActions.js │ ├── counterReducer.js │ └── index.jsx ├── package.json ├── public │ └── index.html ├── utils │ └── reactUtils.js └── webpack.config.js ├── exercicios_webpack ├── .gitignore ├── ex.1 │ └── index.js ├── ex.10 │ ├── estilo.css │ └── index.js ├── ex.2 │ ├── index.js │ └── logger.js ├── ex.3 │ ├── duvidaCruel.js │ └── index.js ├── ex.4 │ ├── duvidaCruel.js │ └── index.js ├── ex.5 │ └── index.js ├── ex.6 │ ├── index.js │ └── pessoa.js ├── ex.7 │ └── index.js ├── ex.8 │ └── index.js ├── ex.9 │ └── index.js ├── ex │ ├── estilo.css │ └── index.js ├── package.json ├── public │ └── index.html └── webpack.config.js ├── fundamentos-react ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.jsx │ ├── components │ ├── basicos │ │ ├── Aleatorio.jsx │ │ ├── ComParametro.jsx │ │ ├── Familia.jsx │ │ ├── FamiliaMembro.jsx │ │ ├── Fragmento.jsx │ │ └── Primeiro.jsx │ ├── comunicacao │ │ ├── DiretaFilho.jsx │ │ ├── DiretaPai.jsx │ │ ├── IndiretaFilho.jsx │ │ └── IndiretaPai.jsx │ ├── condicional │ │ ├── If.js │ │ ├── ParOuImpar.jsx │ │ └── UsuarioInfo.jsx │ ├── contador │ │ ├── Botoes.jsx │ │ ├── Contador.css │ │ ├── Contador.jsx │ │ ├── Display.jsx │ │ └── PassoForm.jsx │ ├── formulario │ │ ├── Input.css │ │ └── Input.jsx │ ├── layout │ │ ├── Card.css │ │ └── Card.jsx │ ├── mega │ │ ├── Mega.css │ │ └── Mega.jsx │ └── repeticao │ │ ├── ListaAlunos.jsx │ │ ├── TabelaProdutos.css │ │ └── TabelaProdutos.jsx │ ├── data │ ├── alunos.js │ └── produtos.js │ ├── index.css │ └── index.js ├── hooks ├── .eslintcache ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── components │ │ └── layout │ │ │ ├── Content.css │ │ │ ├── Content.jsx │ │ │ ├── Menu.css │ │ │ ├── Menu.jsx │ │ │ ├── PageTitle.css │ │ │ ├── PageTitle.jsx │ │ │ ├── SectionTitle.css │ │ │ └── SectionTitle.jsx │ ├── data │ │ ├── DataContext.js │ │ └── Store.jsx │ ├── hooks │ │ ├── useCounter.js │ │ └── useFetch.js │ ├── index.css │ ├── index.js │ ├── store │ │ ├── actions │ │ │ ├── index.js │ │ │ ├── number.js │ │ │ └── user.js │ │ ├── index.js │ │ └── reducers │ │ │ ├── index.js │ │ │ ├── number.js │ │ │ └── user.js │ └── views │ │ ├── App.css │ │ ├── App.jsx │ │ └── examples │ │ ├── Home.jsx │ │ ├── NotFound.jsx │ │ ├── UseCallback.jsx │ │ ├── UseCallbackButtons.jsx │ │ ├── UseContext.jsx │ │ ├── UseCustom.jsx │ │ ├── UseEffect.jsx │ │ ├── UseMemo.jsx │ │ ├── UseReducer.jsx │ │ ├── UseRef.jsx │ │ └── UseState.jsx └── yarn.lock ├── index.html ├── my-money-app ├── backend │ ├── .gitignore │ ├── package.json │ └── src │ │ ├── api │ │ ├── billingCycle │ │ │ ├── billingCycle.js │ │ │ └── billingCycleService.js │ │ └── common │ │ │ └── errorHandler.js │ │ ├── config │ │ ├── cors.js │ │ ├── database.js │ │ ├── routes.js │ │ └── server.js │ │ └── loader.js └── frontend │ ├── .gitignore │ ├── package.json │ ├── public │ └── index.html │ ├── src │ ├── billingCycle │ │ ├── billingCycle.jsx │ │ ├── billingCycleActions.js │ │ ├── billingCycleForm.jsx │ │ ├── billingCycleList.jsx │ │ ├── billingCycleReducer.js │ │ ├── itemList.jsx │ │ └── summary.jsx │ ├── common │ │ ├── form │ │ │ ├── input.jsx │ │ │ └── labelAndInput.jsx │ │ ├── layout │ │ │ ├── grid.jsx │ │ │ └── row.jsx │ │ ├── msg │ │ │ └── messages.jsx │ │ ├── operator │ │ │ └── if.jsx │ │ ├── tab │ │ │ ├── tabActions.js │ │ │ ├── tabContent.jsx │ │ │ ├── tabHeader.jsx │ │ │ ├── tabReducer.js │ │ │ ├── tabs.jsx │ │ │ ├── tabsContent.jsx │ │ │ └── tabsHeader.jsx │ │ ├── template │ │ │ ├── content.jsx │ │ │ ├── contentHeader.jsx │ │ │ ├── custom.css │ │ │ ├── dependencies.js │ │ │ ├── footer.jsx │ │ │ ├── header.jsx │ │ │ ├── menu.jsx │ │ │ ├── menuItem.jsx │ │ │ ├── menuTree.jsx │ │ │ └── sideBar.jsx │ │ └── widget │ │ │ └── valueBox.jsx │ ├── dashboard │ │ ├── dashboard.jsx │ │ ├── dashboardActions.js │ │ └── dashboardReducer.js │ ├── dashboard2 │ │ └── dashboard2.jsx │ ├── index.jsx │ └── main │ │ ├── app.jsx │ │ ├── reducers.js │ │ └── routes.jsx │ └── webpack.config.js ├── navegacao ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── components │ │ └── layout │ │ │ ├── Content.css │ │ │ ├── Content.jsx │ │ │ ├── Menu.css │ │ │ └── Menu.jsx │ ├── index.css │ ├── index.js │ └── views │ │ ├── App.css │ │ ├── App.jsx │ │ └── examples │ │ ├── About.jsx │ │ ├── Home.jsx │ │ ├── NotFound.jsx │ │ └── Param.jsx └── yarn.lock ├── novos-projetos ├── calculadora │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ ├── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── components │ │ │ ├── Button.css │ │ │ ├── Button.jsx │ │ │ ├── Display.css │ │ │ └── Display.jsx │ │ ├── fonts │ │ │ └── RobotoMono-Thin.ttf │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ ├── main │ │ │ ├── Calculator.css │ │ │ └── Calculator.jsx │ │ └── registerServiceWorker.js │ └── yarn.lock └── crud │ ├── backend │ ├── db.json │ ├── package-lock.json │ └── package.json │ └── frontend │ ├── .gitignore │ ├── README.md │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ ├── src │ ├── assets │ │ └── imgs │ │ │ └── logo.png │ ├── components │ │ ├── home │ │ │ └── Home.jsx │ │ ├── template │ │ │ ├── Footer.css │ │ │ ├── Footer.jsx │ │ │ ├── Header.css │ │ │ ├── Header.jsx │ │ │ ├── Logo.css │ │ │ ├── Logo.jsx │ │ │ ├── Main.css │ │ │ ├── Main.jsx │ │ │ ├── Nav.css │ │ │ └── Nav.jsx │ │ └── user │ │ │ └── UserCrud.jsx │ ├── index.css │ ├── index.js │ ├── main │ │ ├── App.css │ │ ├── App.jsx │ │ └── Routes.jsx │ └── registerServiceWorker.js │ └── yarn.lock ├── redux-simples ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ ├── Card.css │ ├── Card.jsx │ ├── Intervalo.css │ ├── Intervalo.jsx │ ├── Media.jsx │ ├── Soma.jsx │ └── Sorteio.jsx │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── serviceWorker.js │ ├── setupTests.js │ └── store │ ├── actions │ ├── actionTypes.js │ └── numeros.js │ ├── reducers │ └── numeros.js │ └── storeConfig.js └── todo-app ├── backend ├── .gitignore ├── package.json └── src │ ├── api │ └── todo │ │ ├── todo.js │ │ └── todoService.js │ ├── config │ ├── cors.js │ ├── database.js │ ├── routes.js │ └── server.js │ └── loader.js ├── frontend-sem-redux ├── .gitignore ├── package.json ├── public │ └── index.html ├── src │ ├── about │ │ └── about.jsx │ ├── index.jsx │ ├── main │ │ ├── app.jsx │ │ └── routes.jsx │ ├── template │ │ ├── custom.css │ │ ├── grid.jsx │ │ ├── iconButton.jsx │ │ ├── if.jsx │ │ ├── menu.jsx │ │ └── pageHeader.jsx │ └── todo │ │ ├── todo.jsx │ │ ├── todoForm.jsx │ │ └── todoList.jsx └── webpack.config.js └── frontend ├── .gitignore ├── package.json ├── public └── index.html ├── src ├── about │ └── about.jsx ├── index.jsx ├── main │ ├── app.jsx │ ├── reducers.js │ └── routes.jsx ├── template │ ├── custom.css │ ├── grid.jsx │ ├── iconButton.jsx │ ├── if.jsx │ ├── menu.jsx │ └── pageHeader.jsx └── todo │ ├── todo.jsx │ ├── todoActions.js │ ├── todoForm.jsx │ ├── todoList.jsx │ └── todoReducer.js └── webpack.config.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Curso React-Redux 2 | -------------------------------------------------------------------------------- /exercicios_react/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /exercicios_react/ex.1/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | ReactDOM.render(

Olá React

, document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.10/family.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
5 | {props.children} 6 |
7 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.10/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Family from './family' 5 | import Member from './member' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.10/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.11/family.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
5 | { React.cloneElement(props.children, props) } 6 |
7 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.11/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Family from './family' 5 | import Member from './member' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.11/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.12/family.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
5 | { React.cloneElement(props.children, {...props}) } 6 |
7 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.12/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Family from './family' 5 | import Member from './member' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.12/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.13/family.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
5 | { React.Children.map(props.children, 6 | child => React.cloneElement(child, {...props})) } 7 |
8 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.13/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Family from './family' 5 | import Member from './member' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | 12 | 13 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.13/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.14/family.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { childrenWithProps } from '../utils/reactUtils' 3 | 4 | export default props => ( 5 |
6 | { childrenWithProps(props.children, props) } 7 |
8 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.14/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Family from './family' 5 | import Member from './member' 6 | 7 | ReactDOM.render( 8 | 9 | 10 | 11 | 12 | 13 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.14/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.15/classComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class ClassComponent extends Component { 4 | render() { 5 | return ( 6 |

{this.props.value}

7 | ) 8 | } 9 | } -------------------------------------------------------------------------------- /exercicios_react/ex.15/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import ClassComponent from './classComponent' 5 | 6 | ReactDOM.render( 7 | 8 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.16/classComponent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class ClassComponent extends Component { 4 | 5 | constructor(props) { 6 | super(props) 7 | this.state = { value: props.initialValue } 8 | } 9 | 10 | sum(delta) { 11 | this.setState({ value: this.state.value + delta }) 12 | } 13 | 14 | render() { 15 | return ( 16 |
17 |

{this.props.label}

18 |

{this.state.value}

19 | 20 | 21 |
22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /exercicios_react/ex.16/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import ClassComponent from './classComponent' 5 | 6 | ReactDOM.render( 7 | 8 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.17/field.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Field extends Component { 4 | 5 | constructor(props) { 6 | super(props) 7 | this.state = { value: props.initialValue } 8 | 9 | this.handleChange = this.handleChange.bind(this) 10 | } 11 | 12 | handleChange(event) { 13 | this.setState({ value: event.target.value }) 14 | } 15 | 16 | render() { 17 | return ( 18 |
19 |
20 | 21 |
22 | ) 23 | } 24 | } 25 | 26 | export default Field -------------------------------------------------------------------------------- /exercicios_react/ex.17/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Field from './field' 5 | 6 | ReactDOM.render( 7 | 8 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.18/field.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | class Field extends Component { 5 | 6 | constructor(props) { 7 | super(props) 8 | this.state = { value: props.initialValue } 9 | 10 | this.handleChange = this.handleChange.bind(this) 11 | } 12 | 13 | handleChange(event) { 14 | this.setState({ value: event.target.value }) 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 |
21 | 22 |
23 | ) 24 | } 25 | } 26 | function mapStateToProps(state) { 27 | return { 28 | value: state.field.value 29 | } 30 | } 31 | export default connect(mapStateToProps)(Field) -------------------------------------------------------------------------------- /exercicios_react/ex.18/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { combineReducers, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import Field from './field' 7 | 8 | const reducers = combineReducers({ 9 | field: () => ({ value: 'Opa' }) 10 | }) 11 | 12 | ReactDOM.render( 13 | 14 | 15 | 16 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.19/field.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { bindActionCreators } from 'redux' 4 | import { changeValue } from './fieldActions' 5 | 6 | class Field extends Component { 7 | 8 | constructor(props) { 9 | super(props) 10 | this.state = { value: props.initialValue } 11 | 12 | this.handleChange = this.handleChange.bind(this) 13 | } 14 | 15 | handleChange(event) { 16 | this.setState({ value: event.target.value }) 17 | } 18 | 19 | render() { 20 | return ( 21 |
22 |
23 | 24 |
25 | ) 26 | } 27 | } 28 | function mapStateToProps(state) { 29 | return { 30 | value: state.field.value 31 | } 32 | } 33 | function mapDispatchToProps(dispatch) { 34 | return bindActionCreators({ changeValue }, dispatch) 35 | } 36 | export default connect(mapStateToProps, mapDispatchToProps)(Field) -------------------------------------------------------------------------------- /exercicios_react/ex.19/fieldActions.js: -------------------------------------------------------------------------------- 1 | export function changeValue(e) { 2 | console.log('changeValue') 3 | return { 4 | type: 'VALUE_CHANGED', 5 | payload: e.target.value 6 | } 7 | } -------------------------------------------------------------------------------- /exercicios_react/ex.19/fieldReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = { value: 'Opa' } 2 | 3 | export default function(state = INITIAL_STATE, action) { 4 | switch(action.type) { 5 | case 'VALUE_CHANGED': 6 | return { value: action.payload } 7 | default: 8 | return state 9 | } 10 | } -------------------------------------------------------------------------------- /exercicios_react/ex.19/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { combineReducers, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import Field from './field' 7 | import fieldReducer from './fieldReducer' 8 | 9 | const reducers = combineReducers({ 10 | field: fieldReducer 11 | }) 12 | 13 | ReactDOM.render( 14 | 15 | 16 | 17 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.2/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default function() { 4 | return

Primeiro Componente!

5 | } -------------------------------------------------------------------------------- /exercicios_react/ex.2/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Component from './component.jsx' 5 | 6 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.20/counter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | import { inc, dec, stepChanged } from './counterActions' 5 | 6 | const Counter = props => ( 7 |
8 |

{props.counter.number}

9 | 11 | 12 | 13 |
14 | ) 15 | 16 | const mapStateToProps = state => ({ counter: state.counter }) 17 | const mapDispatchToProps = 18 | dispatch => bindActionCreators({ inc, dec, stepChanged }, dispatch) 19 | export default connect(mapStateToProps, mapDispatchToProps)(Counter) -------------------------------------------------------------------------------- /exercicios_react/ex.20/counterActions.js: -------------------------------------------------------------------------------- 1 | export function inc() { 2 | return { type: 'INC' } 3 | } 4 | 5 | export function dec() { 6 | return { type: 'DEC' } 7 | } 8 | 9 | export function stepChanged(e) { 10 | return { 11 | type: 'STEP_CHANGED', 12 | payload: e.target.value 13 | } 14 | } -------------------------------------------------------------------------------- /exercicios_react/ex.20/counterReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = { step: 1, number: 0 } 2 | 3 | export default function(state = INITIAL_STATE, action) { 4 | switch(action.type) { 5 | case 'INC': 6 | return { ...state, number: state.number + state.step } 7 | case 'DEC': 8 | return { ...state, number: state.number - state.step } 9 | case 'STEP_CHANGED': 10 | return { ...state, step: +action.payload } 11 | default: 12 | return state 13 | } 14 | } -------------------------------------------------------------------------------- /exercicios_react/ex.20/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { combineReducers, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import counterReducer from './counterReducer' 7 | import Counter from './counter' 8 | 9 | const reducers = combineReducers({ 10 | counter: counterReducer 11 | }) 12 | 13 | ReactDOM.render( 14 | 15 | 16 | 17 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.3/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default function() { 4 | return

Primeiro Componente!

5 | } -------------------------------------------------------------------------------- /exercicios_react/ex.3/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Component from './component' 5 | 6 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.4/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default () => ( 4 |

Primeiro Componente!

5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.4/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Component from './component' 5 | 6 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.5/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |

{props.value}

5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.5/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Component from './component' 5 | 6 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.6/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Primeiro = props => ( 4 |

Primeiro Componente!

5 | ) 6 | 7 | const Segundo = props => ( 8 |

Segundo Componente!

9 | ) 10 | 11 | export { Primeiro, Segundo } -------------------------------------------------------------------------------- /exercicios_react/ex.6/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import { Primeiro, Segundo } from './component' 5 | 6 | ReactDOM.render( 7 |
8 | 9 | 10 |
11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.7/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const Primeiro = props => ( 4 |

Primeiro Componente!

5 | ) 6 | 7 | export const Segundo = props => ( 8 |

Segundo Componente!

9 | ) 10 | 11 | // export { Primeiro, Segundo } -------------------------------------------------------------------------------- /exercicios_react/ex.7/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import { Primeiro, Segundo } from './component' 5 | 6 | ReactDOM.render( 7 |
8 | 9 | 10 |
11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.8/component.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |

Primeiro Componente!

5 | ) 6 | 7 | export const Segundo = props => ( 8 |

Segundo Componente!

9 | ) 10 | 11 | // export { Primeiro, Segundo } -------------------------------------------------------------------------------- /exercicios_react/ex.8/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import Primeiro, { Segundo } from './component' 5 | 6 | ReactDOM.render( 7 |
8 | 9 | 10 |
11 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.9/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | 4 | import SilvaFamily from './silvaFamily' 5 | 6 | ReactDOM.render( 7 | 8 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/ex.9/member.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
{props.name} {props.lastName}
5 | ) -------------------------------------------------------------------------------- /exercicios_react/ex.9/silvaFamily.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Member from './member' 3 | 4 | export default props => ( 5 |
6 | 7 | 8 | 9 | 10 |
11 | ) -------------------------------------------------------------------------------- /exercicios_react/ex/counter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | import { inc, dec, stepChanged } from './counterActions' 5 | 6 | const Counter = props => ( 7 |
8 |

{props.counter.number}

9 | 11 | 12 | 13 |
14 | ) 15 | 16 | const mapStateToProps = state => ({ counter: state.counter }) 17 | const mapDispatchToProps = 18 | dispatch => bindActionCreators({ inc, dec, stepChanged }, dispatch) 19 | export default connect(mapStateToProps, mapDispatchToProps)(Counter) -------------------------------------------------------------------------------- /exercicios_react/ex/counterActions.js: -------------------------------------------------------------------------------- 1 | export function inc() { 2 | return { type: 'INC' } 3 | } 4 | 5 | export function dec() { 6 | return { type: 'DEC' } 7 | } 8 | 9 | export function stepChanged(e) { 10 | return { 11 | type: 'STEP_CHANGED', 12 | payload: e.target.value 13 | } 14 | } -------------------------------------------------------------------------------- /exercicios_react/ex/counterReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = { step: 1, number: 0 } 2 | 3 | export default function(state = INITIAL_STATE, action) { 4 | switch(action.type) { 5 | case 'INC': 6 | return { ...state, number: state.number + state.step } 7 | case 'DEC': 8 | return { ...state, number: state.number - state.step } 9 | case 'STEP_CHANGED': 10 | return { ...state, step: +action.payload } 11 | default: 12 | return state 13 | } 14 | } -------------------------------------------------------------------------------- /exercicios_react/ex/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { combineReducers, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import counterReducer from './counterReducer' 7 | import Counter from './counter' 8 | 9 | const reducers = combineReducers({ 10 | counter: counterReducer 11 | }) 12 | 13 | ReactDOM.render( 14 | 15 | 16 | 17 | , document.getElementById('app')) -------------------------------------------------------------------------------- /exercicios_react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exercicios_react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --progress --colors --inline --hot" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-core": "^6.22.1", 14 | "babel-loader": "^6.2.10", 15 | "babel-plugin-transform-object-rest-spread": "^6.22.0", 16 | "babel-preset-es2015": "^6.22.0", 17 | "babel-preset-react": "^6.22.0", 18 | "react": "^15.4.2", 19 | "react-dom": "^15.4.2", 20 | "react-redux": "^5.0.2", 21 | "redux": "^3.6.0", 22 | "webpack": "^1.14.0", 23 | "webpack-dev-server": "^1.16.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /exercicios_react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Exercícios de React 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /exercicios_react/utils/reactUtils.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | // Adicionado no ex.14 4 | function childrenWithProps(children, props) { 5 | return React.Children.map(children, 6 | child => React.cloneElement(child, {...props})) 7 | } 8 | 9 | export { childrenWithProps } -------------------------------------------------------------------------------- /exercicios_react/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | 3 | module.exports = { 4 | entry: './ex/index.jsx', 5 | output: { 6 | path: __dirname + '/public', 7 | filename: './bundle.js' 8 | }, 9 | devServer: { 10 | port: 8080, 11 | contentBase: './public', 12 | }, 13 | // Adicionado no ex.3 14 | resolve: { 15 | extensions: ['', '.js', '.jsx'] 16 | }, 17 | module: { 18 | loaders: [{ 19 | test: /.js[x]?$/, 20 | loader: 'babel-loader', 21 | exclude: /node_modules/, 22 | query: { 23 | presets: ['es2015', 'react'], 24 | // O plugin foi adicionado no ex.12 25 | plugins: ['transform-object-rest-spread'] 26 | } 27 | }] 28 | } 29 | } -------------------------------------------------------------------------------- /exercicios_webpack/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /exercicios_webpack/ex.1/index.js: -------------------------------------------------------------------------------- 1 | console.log('Webpack') -------------------------------------------------------------------------------- /exercicios_webpack/ex.10/estilo.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #253B6E; 3 | } -------------------------------------------------------------------------------- /exercicios_webpack/ex.10/index.js: -------------------------------------------------------------------------------- 1 | import './estilo.css' 2 | import 'react' 3 | 4 | export default props => ( 5 |

Olá

6 | ) 7 | 8 | console.log('Funcionou!') -------------------------------------------------------------------------------- /exercicios_webpack/ex.2/index.js: -------------------------------------------------------------------------------- 1 | const logger = require('./logger') 2 | logger.info('Usando o padrão CommonJS!') -------------------------------------------------------------------------------- /exercicios_webpack/ex.2/logger.js: -------------------------------------------------------------------------------- 1 | function info(text) { 2 | console.log(`INFO: ${text}`) 3 | } 4 | 5 | module.exports = { info } -------------------------------------------------------------------------------- /exercicios_webpack/ex.3/duvidaCruel.js: -------------------------------------------------------------------------------- 1 | console.log('Sou carregado?') -------------------------------------------------------------------------------- /exercicios_webpack/ex.3/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Quando o arquivo não é referenciado 3 | * ele não será considerado para a geração 4 | * do arquivo bundle.js 5 | */ -------------------------------------------------------------------------------- /exercicios_webpack/ex.4/duvidaCruel.js: -------------------------------------------------------------------------------- 1 | console.log('Sou carregado?') -------------------------------------------------------------------------------- /exercicios_webpack/ex.4/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Quando o arquivo é referenciado ele será 3 | * considerado para a geração do arquivo bundle.js 4 | */ 5 | require('./duvidaCruel') -------------------------------------------------------------------------------- /exercicios_webpack/ex.5/index.js: -------------------------------------------------------------------------------- 1 | class Pessoa { 2 | constructor(nome) { 3 | this.nome = nome 4 | } 5 | 6 | toString() { 7 | return `Pessoa: ${this.nome}` 8 | } 9 | } 10 | 11 | const pessoa = new Pessoa('Guilherme') 12 | console.log(pessoa.toString()) -------------------------------------------------------------------------------- /exercicios_webpack/ex.6/index.js: -------------------------------------------------------------------------------- 1 | import Pessoa from './pessoa' 2 | 3 | const pessoa = new Pessoa('Guilherme') 4 | console.log(pessoa.toString()) -------------------------------------------------------------------------------- /exercicios_webpack/ex.6/pessoa.js: -------------------------------------------------------------------------------- 1 | export default class Pessoa { 2 | constructor(nome) { 3 | this.nome = nome 4 | } 5 | 6 | toString() { 7 | return `Pessoa: ${this.nome}` 8 | } 9 | } -------------------------------------------------------------------------------- /exercicios_webpack/ex.7/index.js: -------------------------------------------------------------------------------- 1 | const produto = { 2 | nome: 'Caneta Bic Preta', 3 | preco: 1.90, 4 | desconto: 0.05 5 | } 6 | 7 | function clone(objeto) { 8 | return { ...objeto } 9 | } 10 | 11 | const novoProduto = clone(produto) 12 | novoProduto.nome = 'Caneta Bic Azul' 13 | 14 | console.log(produto, novoProduto) -------------------------------------------------------------------------------- /exercicios_webpack/ex.8/index.js: -------------------------------------------------------------------------------- 1 | import 'react' 2 | 3 | export default props => ( 4 | null 5 | ) 6 | 7 | console.log('Funcionou!') -------------------------------------------------------------------------------- /exercicios_webpack/ex.9/index.js: -------------------------------------------------------------------------------- 1 | import 'react' 2 | 3 | export default props => ( 4 |

Olá

5 | ) 6 | 7 | console.log('Funcionou!') -------------------------------------------------------------------------------- /exercicios_webpack/ex/estilo.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #253B6E; 3 | } -------------------------------------------------------------------------------- /exercicios_webpack/ex/index.js: -------------------------------------------------------------------------------- 1 | import './estilo.css' 2 | import 'react' 3 | 4 | export default props => ( 5 |

Olá

6 | ) 7 | 8 | console.log('Funcionou!') -------------------------------------------------------------------------------- /exercicios_webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exercicios_webpack", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --progress --colors --inline --hot" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-core": "^6.22.1", 14 | "babel-loader": "^6.2.10", 15 | "babel-plugin-transform-object-rest-spread": "^6.22.0", 16 | "babel-preset-es2015": "^6.22.0", 17 | "babel-preset-react": "^6.22.0", 18 | "css-loader": "^0.26.1", 19 | "extract-text-webpack-plugin": "^1.0.1", 20 | "react": "^15.4.2", 21 | "style-loader": "^0.13.1", 22 | "webpack": "^1.14.0", 23 | "webpack-dev-server": "^1.16.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /exercicios_webpack/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Exercícios de Webpack 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /exercicios_webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | // ExtractTextPlugin foi adicionado no ex.10 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | module.exports = { 6 | entry: './ex/index.js', 7 | output: { 8 | path: __dirname + '/public', 9 | filename: './bundle.js' 10 | }, 11 | devServer: { 12 | port: 8080, 13 | contentBase: './public' 14 | }, 15 | // ExtractTextPlugin foi adicionado no ex.10 16 | plugins: [ 17 | new ExtractTextPlugin('app.css') 18 | ], 19 | // O loader de js foi adicionado no ex.6 20 | module: { 21 | loaders: [{ 22 | test: /.js?$/, 23 | loader: 'babel-loader', 24 | exclude: /node_modules/, 25 | query: { 26 | // Preset 'react' adicionado no ex.9 27 | presets: ['es2015', 'react'], 28 | // Plugin adicionado no ex.7 29 | plugins: ['transform-object-rest-spread'] 30 | } 31 | }, 32 | // O loader de css foi adicionado no ex.10 33 | { 34 | test: /\.css$/, 35 | loader: ExtractTextPlugin.extract("style-loader", "css-loader") 36 | }] 37 | } 38 | } -------------------------------------------------------------------------------- /fundamentos-react/.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 | -------------------------------------------------------------------------------- /fundamentos-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fundamentos-react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.5.0", 8 | "@testing-library/user-event": "^7.2.1", 9 | "react": "^16.13.1", 10 | "react-dom": "^16.13.1", 11 | "react-scripts": "3.4.1" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build", 16 | "test": "react-scripts test", 17 | "eject": "react-scripts eject" 18 | }, 19 | "eslintConfig": { 20 | "extends": "react-app" 21 | }, 22 | "browserslist": { 23 | "production": [ 24 | ">0.2%", 25 | "not dead", 26 | "not op_mini all" 27 | ], 28 | "development": [ 29 | "last 1 chrome version", 30 | "last 1 firefox version", 31 | "last 1 safari version" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /fundamentos-react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/fundamentos-react/public/favicon.ico -------------------------------------------------------------------------------- /fundamentos-react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | React App 16 | 17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /fundamentos-react/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/fundamentos-react/public/logo192.png -------------------------------------------------------------------------------- /fundamentos-react/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/fundamentos-react/public/logo512.png -------------------------------------------------------------------------------- /fundamentos-react/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 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": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /fundamentos-react/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /fundamentos-react/src/App.css: -------------------------------------------------------------------------------- 1 | .App .Cards { 2 | display: flex; 3 | justify-content: center; 4 | flex-wrap: wrap; 5 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/Aleatorio.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default (props) => { 4 | const { min, max } = props; 5 | const aleatorio = parseInt(Math.random() * (max - min)) + min; 6 | return ( 7 |
8 |

Valor Aleatório

9 |

10 | Valor Mínimo: {min} 11 |

12 |

13 | Valor Máximo: {max} 14 |

15 |

16 | Valor Escolhido: {aleatorio} 17 |

18 |
19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/ComParametro.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function ComParametro(props) { 4 | const status = props.nota >= 7 ? "Aprovado" : "Recuperação"; 5 | const notaInt = Math.ceil(props.nota); 6 | return ( 7 |
8 |

{props.titulo}

9 |

10 | {props.aluno} 11 | tem nota 12 | {notaInt} e está 13 | {status}! 14 |

15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/Familia.jsx: -------------------------------------------------------------------------------- 1 | import React, { cloneElement } from "react"; 2 | 3 | export default (props) => { 4 | return ( 5 |
6 | {props.children.map((child, i) => { 7 | return cloneElement(child, { ...props, key: i }); 8 | })} 9 |
10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/FamiliaMembro.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default (props) => { 4 | return ( 5 |
6 | {props.nome} {props.sobrenome} 7 |
8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/Fragmento.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Fragmento(props) { 4 | return ( 5 | <> 6 |

Fragmento

7 |

Cuidado com esse erro!

8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/basicos/Primeiro.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Primeiro() { 4 | const msg = "Seja bem vindo(a)!"; 5 | return ( 6 |
7 |

Primeiro Componente

8 |

{msg}

9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/comunicacao/DiretaFilho.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | return ( 5 |
6 | {props.nome} 7 | {props.idade} 8 | {props.nerd ? 'Verdadeiro' : 'Falso'}! 9 |
10 | ) 11 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/comunicacao/DiretaPai.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import DiretaFilho from './DiretaFilho' 3 | 4 | export default props => { 5 | return ( 6 |
7 | 8 | 9 |
10 | ) 11 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/comunicacao/IndiretaFilho.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | const cb = props.quandoClicar 5 | const gerarIdade = () => parseInt(Math.random() * (20)) + 50 6 | const gerarNerd = () => Math.random() > 0.5 7 | return ( 8 |
9 |
Filho
10 | 13 |
14 | ) 15 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/comunicacao/IndiretaPai.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import IndiretaFilho from './IndiretaFilho' 3 | 4 | export default props => { 5 | const [nome, setNome] = useState('?') 6 | const [idade, setIdade] = useState(0) 7 | const [nerd, setNerd] = useState(false) 8 | 9 | function fornecerInfomacoes(nome, idade, nerd) { 10 | setNome(nome) 11 | setIdade(idade) 12 | setNerd(nerd) 13 | } 14 | 15 | return ( 16 |
17 |
18 | {nome} 19 | {idade} 20 | {nerd ? 'Verdadeiro' : 'Falso'} 21 |
22 | 23 |
24 | ) 25 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/condicional/If.js: -------------------------------------------------------------------------------- 1 | export default props => { 2 | 3 | const elseChild = props.children.filter(child => { 4 | return child.type && child.type.name === 'Else' 5 | })[0] 6 | 7 | const ifChildren = props.children.filter(child => { 8 | return child !== elseChild 9 | }) 10 | 11 | if(props.test) { 12 | return ifChildren 13 | } else if(elseChild) { 14 | return elseChild 15 | } else { 16 | return false 17 | } 18 | } 19 | 20 | export const Else = props => props.children -------------------------------------------------------------------------------- /fundamentos-react/src/components/condicional/ParOuImpar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default (props) => { 4 | const isPar = props.numero % 2 === 0; 5 | return
{isPar ? Par : Ímpar}
; 6 | }; 7 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/condicional/UsuarioInfo.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import If, { Else } from "./If"; 3 | 4 | export default (props) => { 5 | const usuario = props.usuario || {}; 6 | return ( 7 |
8 | 9 | Seja bem vindo {usuario.nome}! 10 | 11 | Seja bem vindo Amigão! 12 | 13 | 14 |
15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/contador/Botoes.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default (props) => { 4 | return ( 5 |
6 | 7 | 8 |
9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/contador/Contador.css: -------------------------------------------------------------------------------- 1 | .Contador input { 2 | font-size: 1.4rem; 3 | width: 60px; 4 | } 5 | 6 | .Contador button { 7 | margin: 15px; 8 | height: 50px; 9 | width: 50px; 10 | border-radius: 50%; 11 | background-color: #1499D3; 12 | color: #fff; 13 | font-size: 1.4rem; 14 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/contador/Contador.jsx: -------------------------------------------------------------------------------- 1 | import "./Contador.css"; 2 | import React, { Component } from "react"; 3 | 4 | import Display from "./Display"; 5 | import Botoes from "./Botoes"; 6 | import PassoForm from "./PassoForm"; 7 | 8 | class Contador extends Component { 9 | state = { 10 | numero: this.props.numeroInicial || 0, 11 | passo: this.props.passoInicial || 5, 12 | }; 13 | 14 | inc = () => { 15 | this.setState({ 16 | numero: this.state.numero + this.state.passo, 17 | }); 18 | }; 19 | 20 | dec = () => { 21 | this.setState({ 22 | numero: this.state.numero - this.state.passo, 23 | }); 24 | }; 25 | 26 | setPasso = (novoPasso) => { 27 | this.setState({ 28 | passo: novoPasso, 29 | }); 30 | }; 31 | 32 | render() { 33 | return ( 34 |
35 |

Contador

36 | 37 | 38 | 39 |
40 | ); 41 | } 42 | } 43 | 44 | export default Contador; 45 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/contador/Display.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | return ( 5 |

{props.numero}

6 | ) 7 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/contador/PassoForm.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default (props) => { 4 | return ( 5 |
6 | 7 | props.setPasso(+e.target.value)} 12 | /> 13 |
14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/formulario/Input.css: -------------------------------------------------------------------------------- 1 | .Input input { 2 | font-size: 1.4rem; 3 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/formulario/Input.jsx: -------------------------------------------------------------------------------- 1 | import "./Input.css"; 2 | import React, { useState } from "react"; 3 | 4 | export default (props) => { 5 | const [valor, setValor] = useState("Inicial"); 6 | 7 | function quandoMudar(e) { 8 | setValor(e.target.value) 9 | } 10 | 11 | return ( 12 |
13 |

{valor}

14 |
18 | 19 | 20 | 21 |
22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/layout/Card.css: -------------------------------------------------------------------------------- 1 | .Card { 2 | border: 3px solid; 3 | border-radius: 10px; 4 | overflow: hidden; 5 | margin: 10px; 6 | 7 | display: flex; 8 | flex-direction: column; 9 | max-width: 500px; 10 | min-width: 500px; 11 | } 12 | 13 | .Card .Title { 14 | padding: 5px 0px; 15 | display: flex; 16 | justify-content: center; 17 | } 18 | 19 | .Card .Content { 20 | flex-grow: 1; 21 | background-color: #fff; 22 | color: #000; 23 | padding: 10px; 24 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/layout/Card.jsx: -------------------------------------------------------------------------------- 1 | import "./Card.css"; 2 | import React from "react"; 3 | 4 | export default (props) => { 5 | 6 | const cardStyle = { 7 | backgroundColor: props.color || '#F00', 8 | borderColor: props.color || '#F00', 9 | } 10 | 11 | return ( 12 |
13 |
{props.titulo}
14 |
15 | {props.children} 16 |
17 |
18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/mega/Mega.css: -------------------------------------------------------------------------------- 1 | .Mega label { 2 | margin-right: 10px; 3 | } 4 | 5 | .Mega input { 6 | font-size: 1.4rem; 7 | width: 50px; 8 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/mega/Mega.jsx: -------------------------------------------------------------------------------- 1 | import "./Mega.css"; 2 | import React, { useState } from "react"; 3 | 4 | export default (props) => { 5 | function gerarNumeroNaoContido(min, max, array) { 6 | const aleatorio = parseInt(Math.random() * (max + 1 - min)) + min; 7 | return array.includes(aleatorio) 8 | ? gerarNumeroNaoContido(min, max, array) 9 | : aleatorio; 10 | } 11 | 12 | function gerarNumeros(qtde) { 13 | const numeros = Array(qtde) 14 | .fill(0) 15 | .reduce((nums) => { 16 | const novoNumero = gerarNumeroNaoContido(1, 60, nums); 17 | return [...nums, novoNumero]; 18 | }, []) 19 | .sort((n1, n2) => n1 - n2); 20 | 21 | return numeros; 22 | } 23 | 24 | const [qtde, setQtde] = useState(props.qtde || 6); 25 | const numerosIniciais = gerarNumeros(qtde); 26 | const [numeros, setNumeros] = useState(numerosIniciais); 27 | 28 | return ( 29 |
30 |

Mega

31 |

{numeros.join(" ")}

32 |
33 | 34 | { 40 | setQtde(+e.target.value) 41 | setNumeros(gerarNumeros(+e.target.value)) 42 | }} 43 | /> 44 |
45 | 48 |
49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/repeticao/ListaAlunos.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import alunos from "../../data/alunos"; 3 | 4 | export default (props) => { 5 | const alunosLI = alunos.map((aluno) => { 6 | return ( 7 |
  • 8 | {aluno.id}) {aluno.nome} -> {aluno.nota} 9 |
  • 10 | ); 11 | }); 12 | 13 | return ( 14 |
    15 |
      {alunosLI}
    16 |
    17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /fundamentos-react/src/components/repeticao/TabelaProdutos.css: -------------------------------------------------------------------------------- 1 | .TabelaProdutos table { 2 | width: 100%; 3 | } 4 | 5 | .TabelaProdutos th { 6 | background-color: #283cae; 7 | color: #fff; 8 | } 9 | 10 | .TabelaProdutos .Par { 11 | background-color: #ddd; 12 | } 13 | 14 | .TabelaProdutos .Impar { 15 | background-color: #ccc; 16 | } -------------------------------------------------------------------------------- /fundamentos-react/src/components/repeticao/TabelaProdutos.jsx: -------------------------------------------------------------------------------- 1 | import './TabelaProdutos.css' 2 | import React from "react"; 3 | import produtos from "../../data/produtos"; 4 | 5 | export default (props) => { 6 | 7 | function getLinhas() { 8 | return produtos.map((produto, i) => { 9 | return ( 10 | 12 | {produto.id} 13 | {produto.nome} 14 | R$ {produto.preco.toFixed(2).replace('.', ',')} 15 | 16 | ) 17 | }) 18 | } 19 | 20 | return ( 21 |
    22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {getLinhas()} 32 | 33 |
    IdNomePreço
    34 |
    35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /fundamentos-react/src/data/alunos.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { id: 1, nome: 'Ana', nota: 6.2 }, 3 | { id: 2, nome: 'Bia', nota: 7.6 }, 4 | { id: 3, nome: 'Carlos', nota: 8.1 }, 5 | { id: 4, nome: 'Daniel', nota: 5.7 }, 6 | { id: 5, nome: 'Gui', nota: 10.0 }, 7 | { id: 6, nome: 'Rebeca', nota: 9.5 }, 8 | { id: 7, nome: 'Arthur', nota: 7.7 }, 9 | { id: 8, nome: 'Pedro', nota: 6.9 }, 10 | { id: 9, nome: 'Gustavo', nota: 8.8 }, 11 | ] -------------------------------------------------------------------------------- /fundamentos-react/src/data/produtos.js: -------------------------------------------------------------------------------- 1 | const produtos = [ 2 | { id: 1, nome: 'Caneta', preco: 2.99 }, 3 | { id: 2, nome: 'Lapis', preco: 1.99 }, 4 | { id: 3, nome: 'iPad', preco: 5899.99 }, 5 | { id: 4, nome: 'Sansung S20 Ultra', preco: 6599.99 }, 6 | { id: 5, nome: 'Notebook', preco: 3409.99 }, 7 | { id: 6, nome: 'Caderno', preco: 19.99 }, 8 | { id: 7, nome: 'Borracha', preco: 4.99 }, 9 | { id: 8, nome: 'Impressora', preco: 889.99 }, 10 | { id: 9, nome: 'Monitor 27', preco: 799.9912334 }, 11 | { id: 10, nome: 'Cadeira', preco: 1239.99 }, 12 | ] 13 | 14 | export default produtos -------------------------------------------------------------------------------- /fundamentos-react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Oswald; 3 | background-color: #222; 4 | color: #fff; 5 | text-align: center; 6 | font-size: 1.4rem; 7 | } 8 | 9 | h1, h2, h3 { 10 | font-weight: 200; 11 | } 12 | 13 | h2, h3 { 14 | margin: 0; 15 | } 16 | -------------------------------------------------------------------------------- /fundamentos-react/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import ReactDOM from 'react-dom' 3 | import React from 'react' 4 | 5 | import App from './App' 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('root') 10 | ) -------------------------------------------------------------------------------- /hooks/.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 | -------------------------------------------------------------------------------- /hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hooks", 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 | "react": "^17.0.1", 10 | "react-dom": "^17.0.1", 11 | "react-router-dom": "^5.2.0", 12 | "react-scripts": "4.0.1", 13 | "web-vitals": "^0.2.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /hooks/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/hooks/public/favicon.ico -------------------------------------------------------------------------------- /hooks/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
    32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /hooks/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/hooks/public/logo192.png -------------------------------------------------------------------------------- /hooks/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/hooks/public/logo512.png -------------------------------------------------------------------------------- /hooks/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 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": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /hooks/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /hooks/src/components/layout/Content.css: -------------------------------------------------------------------------------- 1 | .Content { 2 | display: flex; 3 | flex-grow: 1; 4 | background-color: #ececec; 5 | padding: 30px; 6 | } 7 | 8 | .Content > * { 9 | display: flex; 10 | flex: 1; 11 | flex-direction: column; 12 | } -------------------------------------------------------------------------------- /hooks/src/components/layout/Content.jsx: -------------------------------------------------------------------------------- 1 | import './Content.css' 2 | import React from 'react' 3 | import { Switch, Route } from 'react-router-dom' 4 | 5 | import Home from '../../views/examples/Home' 6 | import NotFound from '../../views/examples/NotFound' 7 | import UseState from '../../views/examples/UseState' 8 | import UseEffect from '../../views/examples/UseEffect' 9 | import UseRef from '../../views/examples/UseRef' 10 | import UseCallback from '../../views/examples/UseCallback' 11 | import UseMemo from '../../views/examples/UseMemo' 12 | import UseContext from '../../views/examples/UseContext' 13 | import UseReducer from '../../views/examples/UseReducer' 14 | import UseCustom from '../../views/examples/UseCustom' 15 | 16 | const Content = props => ( 17 |
    18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
    51 | ) 52 | 53 | export default Content -------------------------------------------------------------------------------- /hooks/src/components/layout/Menu.css: -------------------------------------------------------------------------------- 1 | .Menu { 2 | display: flex; 3 | flex-basis: 250px; 4 | 5 | background: linear-gradient(to top, #00b4db, #006c90); 6 | 7 | z-index: 1; 8 | -webkit-box-shadow: 4px 0px 17px -5px rgba(0,0,0,0.75); 9 | -moz-box-shadow: 4px 0px 17px -5px rgba(0,0,0,0.75); 10 | box-shadow: 4px 0px 17px -5px rgba(0,0,0,0.75); 11 | } 12 | 13 | .Menu nav { 14 | flex-grow: 1; 15 | } 16 | 17 | .Menu ul { 18 | list-style: none; 19 | padding: 0; 20 | } 21 | 22 | .Menu li { 23 | display: flex; 24 | } 25 | 26 | .Menu li a { 27 | flex: 1; 28 | padding: 10px; 29 | margin-bottom: 10px; 30 | 31 | text-decoration: none; 32 | color: #fff; 33 | font-size: 1.5rem; 34 | } 35 | 36 | .Menu li a:hover { 37 | background: #00000020; 38 | } -------------------------------------------------------------------------------- /hooks/src/components/layout/Menu.jsx: -------------------------------------------------------------------------------- 1 | import './Menu.css' 2 | import React from 'react' 3 | 4 | import { Link } from 'react-router-dom' 5 | 6 | const Menu = props => ( 7 | 40 | ) 41 | 42 | export default Menu -------------------------------------------------------------------------------- /hooks/src/components/layout/PageTitle.css: -------------------------------------------------------------------------------- 1 | .PageTitle { 2 | border-left: 10px solid #006c90; 3 | padding: 15px; 4 | background: #006c9025; 5 | margin-bottom: 40px; 6 | } 7 | 8 | .PageTitle h1 { 9 | margin: 0; 10 | font-weight: 400; 11 | } 12 | 13 | .PageTitle h2 { 14 | margin-top: 5px; 15 | margin-bottom: 0px; 16 | font-weight: 300; 17 | } 18 | 19 | .PageTitle.error{ 20 | border-left: 12px solid#cb2d3e; 21 | background:#cb2d3e25; 22 | } -------------------------------------------------------------------------------- /hooks/src/components/layout/PageTitle.jsx: -------------------------------------------------------------------------------- 1 | import './PageTitle.css' 2 | import React from 'react' 3 | 4 | const PageTitle = props => ( 5 |
    6 |

    {props.title}

    7 |

    {props.subtitle}

    8 |
    9 | ) 10 | 11 | export default PageTitle -------------------------------------------------------------------------------- /hooks/src/components/layout/SectionTitle.css: -------------------------------------------------------------------------------- 1 | .SectionTitle { 2 | border-bottom: 3px solid #006c90; 3 | } 4 | 5 | .SectionTitle h3 { 6 | margin: 0; 7 | margin-bottom: 5px; 8 | font-size: 2rem; 9 | font-weight: 400; 10 | } -------------------------------------------------------------------------------- /hooks/src/components/layout/SectionTitle.jsx: -------------------------------------------------------------------------------- 1 | import './SectionTitle.css' 2 | import React from 'react' 3 | 4 | const SectionTitle = props => ( 5 |
    6 |

    {props.title}

    7 |
    8 | ) 9 | 10 | export default SectionTitle -------------------------------------------------------------------------------- /hooks/src/data/DataContext.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const data = { 4 | number: 123, 5 | text: 'Context API...' 6 | } 7 | 8 | const DataContext = React.createContext(data) 9 | 10 | export default DataContext -------------------------------------------------------------------------------- /hooks/src/data/Store.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | 3 | const initialState = { 4 | number: 1234, 5 | text: 'Context API + Hooks' 6 | } 7 | 8 | export const AppContext = React.createContext(initialState) 9 | 10 | const Store = props => { 11 | const [state, setState] = useState(initialState) 12 | 13 | function updateState(key, value) { 14 | setState({ 15 | ...state, 16 | [key]: value 17 | }) 18 | } 19 | 20 | return ( 21 | updateState('number', n), 25 | setText: t => updateState('text', t), 26 | }}> 27 | {props.children} 28 | 29 | ) 30 | } 31 | 32 | export default Store -------------------------------------------------------------------------------- /hooks/src/hooks/useCounter.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | export const useCounter = (initialValue = 100) => { 4 | const [count, setCount] = useState(initialValue) 5 | 6 | function inc() { 7 | setCount(count + 1) 8 | } 9 | 10 | function dec() { 11 | setCount(count - 1) 12 | } 13 | 14 | return [count, inc, dec] 15 | } -------------------------------------------------------------------------------- /hooks/src/hooks/useFetch.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | export const useFetch = (url, method = 'get') => { 4 | const [response, setResponse] = useState({ 5 | data: null, 6 | loading: true 7 | }) 8 | 9 | useEffect(function() { 10 | fetch(url, { method }) 11 | .then(resp => resp.json()) 12 | .then(json => setResponse({ 13 | data: json, 14 | loading: false 15 | })) 16 | }, [url, method]) 17 | 18 | return response 19 | } -------------------------------------------------------------------------------- /hooks/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: 'Montserrat', sans-serif; 4 | } 5 | 6 | .text { 7 | font-weight: 300; 8 | font-size: 5rem; 9 | } 10 | 11 | .red { 12 | font-weight: 700; 13 | color: red; 14 | } 15 | 16 | .input { 17 | font-weight: 300; 18 | font-size: 4rem; 19 | margin: 20px 0px; 20 | } 21 | 22 | .btn { 23 | border-radius: 25px; 24 | margin: 10px; 25 | padding: 15px 35px; 26 | border: none; 27 | outline: none; 28 | background-color: #0092c3; 29 | 30 | font-size: 3rem; 31 | color: #fff; 32 | } 33 | 34 | .center { 35 | display: flex; 36 | flex-direction: column; 37 | justify-content: center; 38 | align-items: center; 39 | text-align: center; 40 | } -------------------------------------------------------------------------------- /hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import ReactDOM from 'react-dom' 3 | import React from 'react' 4 | 5 | import App from './views/App' 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('root') 10 | ) -------------------------------------------------------------------------------- /hooks/src/store/actions/index.js: -------------------------------------------------------------------------------- 1 | import { numberAdd2 } from './number' 2 | import { login } from './user' 3 | 4 | export { 5 | numberAdd2, 6 | login 7 | } -------------------------------------------------------------------------------- /hooks/src/store/actions/number.js: -------------------------------------------------------------------------------- 1 | export function numberAdd2(dispatch) { 2 | dispatch({ type: 'numberAdd2' }) 3 | } 4 | -------------------------------------------------------------------------------- /hooks/src/store/actions/user.js: -------------------------------------------------------------------------------- 1 | export function login(dispatch, name) { 2 | dispatch({ type: 'login', payload: name }) 3 | } -------------------------------------------------------------------------------- /hooks/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { reducer } from './reducers' 2 | 3 | const initialState = { 4 | cart: [], 5 | products: [], 6 | user: null, 7 | // foco... 8 | number: 0, 9 | } 10 | 11 | export { 12 | initialState, 13 | reducer 14 | } -------------------------------------------------------------------------------- /hooks/src/store/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { numberReducer } from './number' 2 | import { userReducer } from './user' 3 | 4 | export function reducer(state, action) { 5 | let newState = numberReducer(state, action) 6 | return userReducer(newState, action) 7 | } 8 | -------------------------------------------------------------------------------- /hooks/src/store/reducers/number.js: -------------------------------------------------------------------------------- 1 | export function numberReducer(state, action) { 2 | switch (action.type) { 3 | case 'numberAdd2': 4 | return { ...state, number: state.number + 2 } 5 | case 'numberMulti7': 6 | return { ...state, number: state.number * 7 } 7 | case 'numberDiv25': 8 | return { ...state, number: state.number / 25 } 9 | case 'numberInt': 10 | return { ...state, number: parseInt(state.number) } 11 | case 'numberAddN': 12 | return { ...state, number: state.number + action.payload } 13 | default: 14 | return state 15 | } 16 | } -------------------------------------------------------------------------------- /hooks/src/store/reducers/user.js: -------------------------------------------------------------------------------- 1 | export function userReducer(state, action) { 2 | switch (action.type) { 3 | case 'login': 4 | return { ...state, user: { name: action.payload } } 5 | default: 6 | return state 7 | } 8 | } -------------------------------------------------------------------------------- /hooks/src/views/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | display: flex; 3 | height: 100vh; 4 | } -------------------------------------------------------------------------------- /hooks/src/views/App.jsx: -------------------------------------------------------------------------------- 1 | import './App.css' 2 | import React, { useState } from 'react' 3 | import { BrowserRouter as Router } from 'react-router-dom' 4 | 5 | import Menu from '../components/layout/Menu' 6 | import Content from '../components/layout/Content' 7 | 8 | import DataContext, { data } from '../data/DataContext' 9 | import Store from '../data/Store' 10 | 11 | const App = props => { 12 | const [state, setState] = useState(data) 13 | 14 | return ( 15 | 16 | 17 |
    18 | 19 | 20 | 21 | 22 |
    23 |
    24 |
    25 | ) 26 | } 27 | 28 | export default App -------------------------------------------------------------------------------- /hooks/src/views/examples/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | 4 | const Home = props => ( 5 |
    6 | 9 |
    10 | ) 11 | 12 | export default Home -------------------------------------------------------------------------------- /hooks/src/views/examples/NotFound.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | 4 | const Home = props => ( 5 |
    6 | 9 |
    10 | ) 11 | 12 | export default Home -------------------------------------------------------------------------------- /hooks/src/views/examples/UseCallback.jsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import UseCallbackButtons from './UseCallbackButtons' 4 | 5 | 6 | const UseCallback = props => { 7 | const [count, setCount] = useState(0) 8 | 9 | const inc = useCallback(function (delta) { 10 | setCount(curr => curr + delta) 11 | }, [setCount]) 12 | 13 | return ( 14 |
    15 | 18 | 19 |
    20 | {count} 21 | 22 |
    23 |
    24 | ) 25 | } 26 | 27 | export default UseCallback -------------------------------------------------------------------------------- /hooks/src/views/examples/UseCallbackButtons.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const UseCallbackButtons = (props) => { 4 | console.log('render....') 5 | return ( 6 |
    7 | 10 | 13 | 16 |
    17 | ) 18 | } 19 | 20 | // export default UseCallbackButtons 21 | export default React.memo(UseCallbackButtons) -------------------------------------------------------------------------------- /hooks/src/views/examples/UseContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import SectionTitle from '../../components/layout/SectionTitle' 4 | 5 | import DataContext from '../../data/DataContext' 6 | import { AppContext } from '../../data/Store' 7 | 8 | const UseContext = (props) => { 9 | const { state, setState } = useContext(DataContext) 10 | 11 | function addNumber(delta) { 12 | setState({ 13 | ...state, 14 | number: state.number + delta, 15 | }) 16 | } 17 | 18 | const { number, text, setNumber } = useContext(AppContext) 19 | 20 | return ( 21 |
    22 | 26 | 27 | 28 |
    29 | {state.text} 30 | {state.number} 31 | 32 |
    33 | 36 | 39 |
    40 |
    41 | 42 | 43 |
    44 | {text} 45 | {number} 46 |
    47 | 52 | 57 |
    58 |
    59 |
    60 | ) 61 | } 62 | 63 | export default UseContext 64 | -------------------------------------------------------------------------------- /hooks/src/views/examples/UseCustom.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import SectionTitle from '../../components/layout/SectionTitle' 4 | import { useCounter } from '../../hooks/useCounter' 5 | import { useFetch } from '../../hooks/useFetch' 6 | 7 | const UseRef = props => { 8 | 9 | const [count, inc, dec] = useCounter(10) 10 | 11 | const url = 'http://files.cod3r.com.br/curso-react/estados.json' 12 | const response = useFetch(url) 13 | 14 | function showStates(states) { 15 | return states.map(state =>
  • {state.nome} - {state.sigla}
  • ) 16 | } 17 | 18 | return ( 19 |
    20 | 23 | 24 | 25 |
    26 | {count} 27 |
    28 | 30 | 32 |
    33 |
    34 | 35 |
    36 |
      37 | {!response.loading ? showStates(response.data) : false} 38 |
    39 |
    40 |
    41 | ) 42 | } 43 | 44 | export default UseRef -------------------------------------------------------------------------------- /hooks/src/views/examples/UseEffect.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import SectionTitle from '../../components/layout/SectionTitle' 4 | 5 | function calcFatorial(num) { 6 | const n = parseInt(num) 7 | if(n < 0) return -1 8 | if(n === 0) return 1 9 | return calcFatorial(n - 1) * n 10 | } 11 | 12 | const UseEffect = (props) => { 13 | 14 | // Ex #01 15 | const [number, setNumber] = useState(1) 16 | const [fatorial, setFatorial] = useState(1) 17 | 18 | useEffect(function() { 19 | setFatorial(calcFatorial(number)) 20 | }, [number]) 21 | 22 | useEffect(function() { 23 | if(fatorial > 1000000) { 24 | document.title = "Eita!!!" 25 | } 26 | }, [fatorial]) 27 | 28 | // Ex #02 29 | const [status, setStatus] = useState("Ímpar") 30 | 31 | useEffect(function() { 32 | setStatus(number % 2 === 0 ? "Par" : "Ímpar") 33 | }, [number]) 34 | 35 | return ( 36 |
    37 | 40 | 41 | 42 |
    43 |
    44 | Fatorial: 45 | {fatorial === -1 ? 'Não existe' : fatorial} 46 |
    47 | setNumber(e.target.value)} /> 50 |
    51 | 52 | 53 |
    54 |
    55 | Status: 56 | {status} 57 |
    58 |
    59 |
    60 | ) 61 | } 62 | 63 | export default UseEffect 64 | -------------------------------------------------------------------------------- /hooks/src/views/examples/UseMemo.jsx: -------------------------------------------------------------------------------- 1 | import React, { useMemo, useState } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | 4 | function sum(a, b) { 5 | const future = Date.now() + 2000 6 | while(Date.now() < future) {} // espera... 2s 7 | return a + b 8 | } 9 | 10 | const UseMemo = props => { 11 | const [n1, setN1] = useState(0) 12 | const [n2, setN2] = useState(0) 13 | const [n3, setN3] = useState(0) 14 | 15 | const result = useMemo(() => sum(n1, n2), [n1, n2]) 16 | 17 | return ( 18 |
    19 | 22 | 23 |
    24 | setN1(parseInt(e.target.value))}/> 26 | setN2(parseInt(e.target.value))}/> 28 | setN3(parseInt(e.target.value))}/> 30 | {result} 31 |
    32 |
    33 | ) 34 | } 35 | 36 | export default UseMemo -------------------------------------------------------------------------------- /hooks/src/views/examples/UseRef.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef, useState } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import SectionTitle from '../../components/layout/SectionTitle' 4 | 5 | const merge = function(s1, s2) { 6 | return [...s1].map((e, i) => `${e}${s2[i] || ""}`).join("") 7 | } 8 | 9 | const UseRef = props => { 10 | const [value1, setValue1] = useState("") 11 | const [value2, setValue2] = useState("") 12 | 13 | const count = useRef(0) 14 | const myInput1 = useRef(null) 15 | const myInput2 = useRef(null) 16 | 17 | useEffect(function() { 18 | count.current = count.current + 1 19 | myInput2.current.focus() 20 | }, [value1]) 21 | 22 | useEffect(function() { 23 | count.current++ 24 | myInput1.current.focus() 25 | }, [value2]) 26 | 27 | 28 | return ( 29 |
    30 | 33 | 34 | 35 |
    36 |
    37 | Valor: 38 | {merge(value1, value2)} [ 39 | {count.current} 40 | ] 41 |
    42 | 43 | setValue1(e.target.value)} /> 46 |
    47 | 48 | 49 |
    50 | setValue2(e.target.value)}/> 53 |
    54 |
    55 | ) 56 | } 57 | 58 | export default UseRef -------------------------------------------------------------------------------- /hooks/src/views/examples/UseState.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import PageTitle from '../../components/layout/PageTitle' 3 | import SectionTitle from '../../components/layout/SectionTitle' 4 | 5 | const UseState = (props) => { 6 | const [count, setCount] = useState(0) 7 | const [name, setName] = useState("") 8 | 9 | return ( 10 |
    11 | 14 | 15 | 16 |
    17 | {count} 18 |
    19 | 21 | 23 | 25 |
    26 |
    27 | 28 | 29 | setName(e.target.value)} /> 31 | {name} 32 |
    33 | ) 34 | } 35 | 36 | export default UseState 37 | -------------------------------------------------------------------------------- /my-money-app/backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /my-money-app/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-money-backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/loader.js", 6 | "scripts": { 7 | "dev": "nodemon", 8 | "production": "pm2 start src/loader.js --name my-money-backend" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "body-parser": "^1.15.2", 15 | "express": "^4.14.0", 16 | "express-query-int": "^1.0.1", 17 | "lodash": "^4.17.4", 18 | "mongoose": "^4.7.0", 19 | "mongoose-paginate": "^5.0.3", 20 | "node-restful": "^0.2.5", 21 | "pm2": "^2.1.5" 22 | }, 23 | "devDependencies": { 24 | "nodemon": "^1.11.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /my-money-app/backend/src/api/billingCycle/billingCycle.js: -------------------------------------------------------------------------------- 1 | const restful = require('node-restful') 2 | const mongoose = restful.mongoose 3 | 4 | const creditSchema = new mongoose.Schema({ 5 | name: { type: String, required: true }, 6 | value: { type: Number, min: 0, required: true } 7 | }) 8 | 9 | const debtSchema = new mongoose.Schema({ 10 | name: { type: String, required: true }, 11 | value: { type: Number, min: 0, required: [true, 'Informe o valor do débito!'] }, 12 | status: { type: String, required: false, uppercase: true, 13 | enum: ['PAGO', 'PENDENTE', 'AGENDADO'] } 14 | }) 15 | 16 | const billingCycleSchema = new mongoose.Schema({ 17 | name: { type: String, required: true }, 18 | month: { type: Number, min: 1, max: 12, required: true }, 19 | year: { type: Number, min: 1970, max: 2100, required: true }, 20 | credits: [creditSchema], 21 | debts: [debtSchema] 22 | }) 23 | 24 | module.exports = restful.model('BillingCycle', billingCycleSchema) -------------------------------------------------------------------------------- /my-money-app/backend/src/api/billingCycle/billingCycleService.js: -------------------------------------------------------------------------------- 1 | const BillingCycle = require('./billingCycle') 2 | const errorHandler = require('../common/errorHandler') 3 | 4 | BillingCycle.methods(['get', 'post', 'put', 'delete']) 5 | BillingCycle.updateOptions({new: true, runValidators: true}) 6 | BillingCycle.after('post', errorHandler).after('put', errorHandler) 7 | 8 | BillingCycle.route('count', (req, res, next) => { 9 | BillingCycle.count((error, value) => { 10 | if(error) { 11 | res.status(500).json({errors: [error]}) 12 | } else { 13 | res.json({value}) 14 | } 15 | }) 16 | }) 17 | 18 | BillingCycle.route('summary', (req, res, next) => { 19 | BillingCycle.aggregate({ 20 | $project: {credit: {$sum: "$credits.value"}, debt: {$sum: "$debts.value"}} 21 | }, { 22 | $group: {_id: null, credit: {$sum: "$credit"}, debt: {$sum: "$debt"}} 23 | }, { 24 | $project: {_id: 0, credit: 1, debt: 1} 25 | }, (error, result) => { 26 | if(error) { 27 | res.status(500).json({errors: [error]}) 28 | } else { 29 | res.json(result[0] || { credit: 0, debt: 0 }) 30 | } 31 | }) 32 | }) 33 | 34 | module.exports = BillingCycle -------------------------------------------------------------------------------- /my-money-app/backend/src/api/common/errorHandler.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash') 2 | 3 | module.exports = (req, res, next) => { 4 | const bundle = res.locals.bundle 5 | 6 | if(bundle.errors) { 7 | const errors = parseErrors(bundle.errors) 8 | res.status(500).json({errors}) 9 | } else { 10 | next() 11 | } 12 | } 13 | 14 | const parseErrors = (nodeRestfulErrors) => { 15 | const errors = [] 16 | _.forIn(nodeRestfulErrors, error => errors.push(error.message)) 17 | return errors 18 | } -------------------------------------------------------------------------------- /my-money-app/backend/src/config/cors.js: -------------------------------------------------------------------------------- 1 | module.exports = (req, res, next) => { 2 | res.header('Access-Control-Allow-Origin', '*') 3 | res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE') 4 | res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept') 5 | next() 6 | } -------------------------------------------------------------------------------- /my-money-app/backend/src/config/database.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | mongoose.Promise = global.Promise 3 | module.exports = mongoose.connect('mongodb://localhost/mymoney') 4 | 5 | mongoose.Error.messages.general.required = "O atributo '{PATH}' é obrigatório." 6 | mongoose.Error.messages.Number.min = 7 | "O '{VALUE}' informado é menor que o limite mínimo de '{MIN}'." 8 | mongoose.Error.messages.Number.max = 9 | "O '{VALUE}' informado é maior que o limite máximo de '{MAX}'." 10 | mongoose.Error.messages.String.enum = 11 | "'{VALUE}' não é válido para o atributo '{PATH}'." -------------------------------------------------------------------------------- /my-money-app/backend/src/config/routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | 3 | module.exports = function(server) { 4 | 5 | // Definir URL base para todas as rotas 6 | const router = express.Router() 7 | server.use('/api', router) 8 | 9 | // Rotas de Ciclo de Pagamento 10 | const BillingCycle = require('../api/billingCycle/billingCycleService') 11 | BillingCycle.register(router, '/billingCycles') 12 | } -------------------------------------------------------------------------------- /my-money-app/backend/src/config/server.js: -------------------------------------------------------------------------------- 1 | const port = 3003 2 | 3 | const bodyParser = require('body-parser') 4 | const express = require('express') 5 | const server = express() 6 | const allowCors = require('./cors') 7 | const queryParser = require('express-query-int') 8 | 9 | server.use(bodyParser.urlencoded({ extended: true })) 10 | server.use(bodyParser.json()) 11 | server.use(allowCors) 12 | server.use(queryParser()) 13 | 14 | server.listen(port, function() { 15 | console.log(`BACKEND is running on port ${port}.`) 16 | }) 17 | 18 | module.exports = server -------------------------------------------------------------------------------- /my-money-app/backend/src/loader.js: -------------------------------------------------------------------------------- 1 | const server = require('./config/server') 2 | require('./config/database') 3 | require('./config/routes')(server) -------------------------------------------------------------------------------- /my-money-app/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /my-money-app/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-money-frontend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --progress --colors --inline --hot", 8 | "production": "webpack --progress -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "admin-lte": "2.3.6", 15 | "axios": "0.15.3", 16 | "babel-core": "6.22.1", 17 | "babel-loader": "6.2.10", 18 | "babel-plugin-react-html-attrs": "2.0.0", 19 | "babel-plugin-transform-object-rest-spread": "6.22.0", 20 | "babel-preset-es2015": "6.22.0", 21 | "babel-preset-react": "6.22.0", 22 | "css-loader": "0.26.1", 23 | "extract-text-webpack-plugin": "1.0.1", 24 | "file-loader": "0.9.0", 25 | "font-awesome": "4.7.0", 26 | "ionicons": "3.0.0", 27 | "lodash": "4.17.4", 28 | "react": "15.4.2", 29 | "react-dom": "15.4.2", 30 | "react-redux": "4.4.6", 31 | "react-redux-toastr": "4.4.2", 32 | "react-router": "3.0.2", 33 | "redux": "3.6.0", 34 | "redux-form": "6.4.1", 35 | "redux-multi": "0.1.12", 36 | "redux-promise": "0.5.3", 37 | "redux-thunk": "2.1.0", 38 | "style-loader": "0.13.1", 39 | "webpack": "1.14.0", 40 | "webpack-dev-server": "1.16.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /my-money-app/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | My Money 7 | 8 | 9 | 10 |
    11 | 12 | 13 | -------------------------------------------------------------------------------- /my-money-app/frontend/src/billingCycle/billingCycle.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | 5 | import ContentHeader from '../common/template/contentHeader' 6 | import Content from '../common/template/content' 7 | import Tabs from '../common/tab/tabs' 8 | import TabsHeader from '../common/tab/tabsHeader' 9 | import TabsContent from '../common/tab/tabsContent' 10 | import TabHeader from '../common/tab/tabHeader' 11 | import TabContent from '../common/tab/tabContent' 12 | import { init, create, update, remove } from './billingCycleActions' 13 | 14 | import List from './billingCycleList' 15 | import Form from './billingCycleForm' 16 | 17 | class BillingCycle extends Component { 18 | 19 | componentWillMount() { 20 | this.props.init() 21 | } 22 | 23 | render() { 24 | return ( 25 |
    26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
    42 | 43 | 44 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 |
    55 | ) 56 | } 57 | } 58 | 59 | const mapDispatchToProps = dispatch => bindActionCreators({ 60 | init, create, update, remove 61 | }, dispatch) 62 | export default connect(null, mapDispatchToProps)(BillingCycle) -------------------------------------------------------------------------------- /my-money-app/frontend/src/billingCycle/billingCycleActions.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { toastr } from 'react-redux-toastr' 3 | import { reset as resetForm, initialize } from 'redux-form' 4 | import { showTabs, selectTab } from '../common/tab/tabActions' 5 | 6 | const BASE_URL = 'http://localhost:3003/api' 7 | const INITIAL_VALUES = {credits: [{}], debts: [{}]} 8 | 9 | export function getList() { 10 | const request = axios.get(`${BASE_URL}/billingCycles`) 11 | return { 12 | type: 'BILLING_CYCLES_FETCHED', 13 | payload: request 14 | } 15 | } 16 | 17 | export function create(values) { 18 | return submit(values, 'post') 19 | } 20 | 21 | export function update(values) { 22 | return submit(values, 'put') 23 | } 24 | 25 | export function remove(values) { 26 | return submit(values, 'delete') 27 | } 28 | 29 | function submit(values, method) { 30 | return dispatch => { 31 | const id = values._id ? values._id : '' 32 | axios[method](`${BASE_URL}/billingCycles/${id}`, values) 33 | .then(resp => { 34 | toastr.success('Sucesso', 'Operação Realizada com sucesso.') 35 | dispatch(init()) 36 | }) 37 | .catch(e => { 38 | e.response.data.errors.forEach(error => toastr.error('Erro', error)) 39 | }) 40 | } 41 | } 42 | 43 | export function showUpdate(billingCycle) { 44 | return [ 45 | showTabs('tabUpdate'), 46 | selectTab('tabUpdate'), 47 | initialize('billingCycleForm', billingCycle) 48 | ] 49 | } 50 | 51 | export function showDelete(billingCycle) { 52 | return [ 53 | showTabs('tabDelete'), 54 | selectTab('tabDelete'), 55 | initialize('billingCycleForm', billingCycle) 56 | ] 57 | } 58 | 59 | export function init() { 60 | return [ 61 | showTabs('tabList', 'tabCreate'), 62 | selectTab('tabList'), 63 | getList(), 64 | initialize('billingCycleForm', INITIAL_VALUES) 65 | ] 66 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/billingCycle/billingCycleList.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | import { getList, showUpdate, showDelete } from './billingCycleActions' 5 | 6 | class BillingCycleList extends Component { 7 | 8 | componentWillMount() { 9 | this.props.getList() 10 | } 11 | 12 | renderRows() { 13 | const list = this.props.list || [] 14 | return list.map(bc => ( 15 | 16 | {bc.name} 17 | {bc.month} 18 | {bc.year} 19 | 20 | 23 | 26 | 27 | 28 | )) 29 | } 30 | 31 | render() { 32 | return ( 33 |
    34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | {this.renderRows()} 45 | 46 |
    NomeMêsAnoAções
    47 |
    48 | ) 49 | } 50 | } 51 | 52 | const mapStateToProps = state => ({list: state.billingCycle.list}) 53 | const mapDispatchToProps = dispatch => bindActionCreators({getList, showUpdate, showDelete}, dispatch) 54 | export default connect(mapStateToProps, mapDispatchToProps)(BillingCycleList) -------------------------------------------------------------------------------- /my-money-app/frontend/src/billingCycle/billingCycleReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = {list: []} 2 | 3 | export default (state = INITIAL_STATE, action) => { 4 | switch (action.type) { 5 | case 'BILLING_CYCLES_FETCHED': 6 | return { ...state, list: action.payload.data } 7 | default: 8 | return state 9 | } 10 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/billingCycle/summary.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | import Grid from '../common/layout/grid' 4 | import Row from '../common/layout/row' 5 | import ValueBox from '../common/widget/valueBox' 6 | 7 | export default ({credit, debt}) => ( 8 | 9 |
    10 | Resumo 11 | 12 | 14 | 16 | 18 | 19 |
    20 |
    21 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/form/input.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 | 9 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/form/labelAndInput.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Grid from '../layout/grid' 3 | 4 | export default props => ( 5 | 6 |
    7 | 8 | 11 |
    12 |
    13 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/layout/grid.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Grid extends Component { 4 | 5 | toCssClasses(numbers) { 6 | const cols = numbers ? numbers.split(' ') : [] 7 | let classes = '' 8 | 9 | if(cols[0]) classes += `col-xs-${cols[0]}` 10 | if(cols[1]) classes += ` col-sm-${cols[1]}` 11 | if(cols[2]) classes += ` col-md-${cols[2]}` 12 | if(cols[3]) classes += ` col-lg-${cols[3]}` 13 | 14 | return classes 15 | } 16 | 17 | render() { 18 | const gridClasses = this.toCssClasses(this.props.cols || '12') 19 | return ( 20 |
    21 | {this.props.children} 22 |
    23 | ) 24 | } 25 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/layout/row.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    {props.children}
    5 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/msg/messages.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReduxToastr from 'react-redux-toastr' 3 | import 'modules/react-redux-toastr/lib/css/react-redux-toastr.css' 4 | 5 | export default props => ( 6 | 14 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/operator/if.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | if(props.test) { 5 | return props.children 6 | } else { 7 | return false 8 | } 9 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabActions.js: -------------------------------------------------------------------------------- 1 | export function selectTab(tabId) { 2 | return { 3 | type: 'TAB_SELECTED', 4 | payload: tabId 5 | } 6 | } 7 | 8 | export function showTabs(...tabIds) { 9 | const tabsToShow = {} 10 | tabIds.forEach(e => tabsToShow[e] = true) 11 | return { 12 | type: 'TAB_SHOWED', 13 | payload: tabsToShow 14 | } 15 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabContent.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | import If from '../operator/if' 5 | 6 | class TabContent extends Component { 7 | render() { 8 | const selected = this.props.tab.selected === this.props.id 9 | const visible = this.props.tab.visible[this.props.id] 10 | return ( 11 | 12 |
    14 | {this.props.children} 15 |
    16 |
    17 | ) 18 | } 19 | } 20 | 21 | const mapStateToProps = state => ({tab: state.tab}) 22 | export default connect(mapStateToProps)(TabContent) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabHeader.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { bindActionCreators } from 'redux' 3 | import { connect } from 'react-redux' 4 | 5 | import If from '../operator/if' 6 | import { selectTab } from './tabActions' 7 | 8 | class TabHeader extends Component { 9 | render() { 10 | const selected = this.props.tab.selected === this.props.target 11 | const visible = this.props.tab.visible[this.props.target] 12 | return ( 13 | 14 |
  • 15 | this.props.selectTab(this.props.target)} 18 | data-target={this.props.target}> 19 | {this.props.label} 20 | 21 |
  • 22 |
    23 | ) 24 | } 25 | } 26 | 27 | const mapStateToProps = state => ({tab : state.tab}) 28 | const mapDispatchToProps = dispatch => bindActionCreators({selectTab}, dispatch) 29 | export default connect(mapStateToProps, mapDispatchToProps)(TabHeader) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = { selected: '', visible: {} } 2 | 3 | export default (state = INITIAL_STATE, action) => { 4 | switch (action.type) { 5 | case 'TAB_SELECTED': 6 | return { ...state, selected: action.payload } 7 | case 'TAB_SHOWED': 8 | return { ...state, visible: action.payload } 9 | default: 10 | return state 11 | } 12 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabs.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 | {props.children} 6 |
    7 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabsContent.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 | {props.children} 6 |
    7 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/tab/tabsHeader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
      5 | {props.children} 6 |
    7 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/content.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    {props.children}
    5 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/contentHeader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 |

    {props.title} {props.small}

    6 |
    7 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/custom.css: -------------------------------------------------------------------------------- 1 | .main-footer { 2 | position: fixed; 3 | bottom:0px; 4 | width:100%; 5 | } 6 | 7 | button { 8 | margin-left: 5px; 9 | } 10 | 11 | .table-actions { 12 | width: 150px; 13 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/dependencies.js: -------------------------------------------------------------------------------- 1 | import 'modules/admin-lte/plugins/jQueryUI/jquery-ui.min' 2 | import 'modules/admin-lte/plugins/fastclick/fastclick' 3 | import 'modules/admin-lte/plugins/slimScroll/jquery.slimscroll.min' 4 | import 'modules/admin-lte/dist/js/app.min' 5 | 6 | import 'modules/font-awesome/css/font-awesome.min.css' 7 | import 'modules/ionicons/dist/css/ionicons.min.css' 8 | import 'modules/admin-lte/bootstrap/css/bootstrap.min.css' 9 | import 'modules/admin-lte/dist/css/AdminLTE.min.css' 10 | import 'modules/admin-lte/dist/css/skins/_all-skins.min.css' 11 | import 'modules/admin-lte/plugins/iCheck/flat/blue.css' 12 | 13 | import './custom.css' -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 | 6 | Copyright © 2017 7 | Cod3r. 8 | 9 |
    10 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 | 6 | MyM 7 | 8 | 9 | My Money 10 | 11 | 12 | 15 |
    16 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/menu.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import MenuItem from './menuItem' 3 | import MenuTree from './menuTree' 4 | 5 | export default props => ( 6 |
      7 | 8 | 9 | 11 | 12 |
    13 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/menuItem.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default props => ( 5 |
  • 6 | 7 | {props.label} 8 | 9 |
  • 10 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/menuTree.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
  • 5 | 6 | {props.label} 7 | 8 | 9 |
      10 | {props.children} 11 |
    12 |
  • 13 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/template/sideBar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Menu from './menu' 3 | 4 | export default props => ( 5 | 10 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/common/widget/valueBox.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Grid from '../layout/grid' 3 | 4 | export default props => ( 5 | 6 |
    7 |
    8 |

    {props.value}

    9 |

    {props.text}

    10 |
    11 |
    12 | 13 |
    14 |
    15 |
    16 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/dashboard/dashboard.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { bindActionCreators } from 'redux' 4 | 5 | import { getSummary } from './dashboardActions' 6 | import ContentHeader from '../common/template/contentHeader' 7 | import Content from '../common/template/content' 8 | import ValueBox from '../common/widget/valueBox' 9 | import Row from '../common/layout/row' 10 | 11 | class Dashboard extends Component { 12 | 13 | componentWillMount() { 14 | this.props.getSummary() 15 | } 16 | 17 | render() { 18 | const { credit, debt } = this.props.summary 19 | return ( 20 |
    21 | 22 | 23 | 24 | 26 | 28 | 30 | 31 | 32 |
    33 | ) 34 | } 35 | } 36 | 37 | const mapStateToProps = state => ({summary: state.dashboard.summary}) 38 | const mapDispatchToProps = dispatch => bindActionCreators({getSummary}, dispatch) 39 | export default connect(mapStateToProps, mapDispatchToProps)(Dashboard) -------------------------------------------------------------------------------- /my-money-app/frontend/src/dashboard/dashboardActions.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | const BASE_URL = 'http://localhost:3003/api' 3 | 4 | export function getSummary() { 5 | const request = axios.get(`${BASE_URL}/billingCycles/summary`) 6 | return { 7 | type: 'BILLING_SUMMARY_FETCHED', 8 | payload: request 9 | } 10 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/dashboard/dashboardReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = {summary: {credit: 0, debt: 0}} 2 | 3 | export default function(state = INITIAL_STATE, action) { 4 | switch (action.type) { 5 | case 'BILLING_SUMMARY_FETCHED': 6 | return { ...state, summary: action.payload.data } 7 | default: 8 | return state 9 | } 10 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/dashboard2/dashboard2.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import axios from 'axios' 3 | 4 | import ContentHeader from '../common/template/contentHeader' 5 | import Content from '../common/template/content' 6 | import ValueBox from '../common/widget/valueBox' 7 | import Row from '../common/layout/row' 8 | 9 | const BASE_URL = 'http://localhost:3003/api' 10 | 11 | export default class Dashboard2 extends Component { 12 | 13 | constructor(props) { 14 | super(props) 15 | this.state = { credit: 0, debt: 0 } 16 | } 17 | 18 | componentWillMount() { 19 | axios.get(`${BASE_URL}/billingCycles/summary`) 20 | .then(resp => this.setState(resp.data)) 21 | } 22 | 23 | render() { 24 | const { credit, debt } = this.state 25 | return ( 26 |
    27 | 28 | 29 | 30 | 32 | 34 | 36 | 37 | 38 |
    39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /my-money-app/frontend/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { applyMiddleware, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import promise from 'redux-promise' 7 | import multi from 'redux-multi' 8 | import thunk from 'redux-thunk' 9 | 10 | import Routes from './main/routes' 11 | import reducers from './main/reducers' 12 | 13 | const devTools = window.__REDUX_DEVTOOLS_EXTENSION__ 14 | && window.__REDUX_DEVTOOLS_EXTENSION__() 15 | const store = applyMiddleware(multi, thunk, promise)(createStore)(reducers, devTools) 16 | ReactDOM.render( 17 | 18 | 19 | 20 | , document.getElementById('app')) -------------------------------------------------------------------------------- /my-money-app/frontend/src/main/app.jsx: -------------------------------------------------------------------------------- 1 | import '../common/template/dependencies' 2 | import React from 'react' 3 | 4 | import Header from '../common/template/header' 5 | import SideBar from '../common/template/sideBar' 6 | import Footer from '../common/template/footer' 7 | import Messages from '../common/msg/messages' 8 | 9 | export default props => ( 10 |
    11 |
    12 | 13 |
    14 | {props.children} 15 |
    16 |
    17 | 18 |
    19 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/src/main/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import { reducer as formReducer } from 'redux-form' 3 | import { reducer as toastrReducer } from 'react-redux-toastr' 4 | 5 | import DashboardReducer from '../dashboard/dashboardReducer' 6 | import TabReducer from '../common/tab/tabReducer' 7 | import BillingCycleReducer from '../billingCycle/billingCycleReducer' 8 | 9 | const rootReducer = combineReducers({ 10 | dashboard: DashboardReducer, 11 | tab: TabReducer, 12 | billingCycle: BillingCycleReducer, 13 | form: formReducer, 14 | toastr: toastrReducer 15 | }) 16 | 17 | export default rootReducer -------------------------------------------------------------------------------- /my-money-app/frontend/src/main/routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Router, Route, IndexRoute, Redirect, hashHistory } from 'react-router' 3 | 4 | import App from './app' 5 | import Dashboard from '../dashboard/dashboard' 6 | import BillingCycle from '../billingCycle/billingCycle' 7 | 8 | export default props => ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ) -------------------------------------------------------------------------------- /my-money-app/frontend/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 3 | 4 | module.exports = { 5 | entry: './src/index.jsx', 6 | output: { 7 | path: __dirname + '/public', 8 | filename: './app.js' 9 | }, 10 | devServer: { 11 | port: 8080, 12 | contentBase: './public', 13 | }, 14 | resolve: { 15 | extensions: ['', '.js', '.jsx'], 16 | alias: { 17 | modules: __dirname + '/node_modules', 18 | jquery: 'modules/admin-lte/plugins/jQuery/jquery-2.2.3.min.js', 19 | bootstrap: 'modules/admin-lte/bootstrap/js/bootstrap.js' 20 | } 21 | }, 22 | plugins: [ 23 | new webpack.ProvidePlugin({ 24 | $: 'jquery', 25 | jQuery: 'jquery', 26 | 'window.jQuery': 'jquery' 27 | }), 28 | new ExtractTextPlugin('app.css') 29 | ], 30 | module: { 31 | loaders: [{ 32 | test: /.js[x]?$/, 33 | loader: 'babel-loader', 34 | exclude: /node_modules/, 35 | query: { 36 | presets: ['es2015', 'react'], 37 | plugins: ['transform-object-rest-spread'] 38 | } 39 | }, { 40 | test: /\.css$/, 41 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 42 | }, { 43 | test: /\.woff|.woff2|.ttf|.eot|.svg|.png|.jpg*.*$/, 44 | loader: 'file' 45 | }] 46 | } 47 | } -------------------------------------------------------------------------------- /navegacao/.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 | -------------------------------------------------------------------------------- /navegacao/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "navegacao", 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 | "react": "^17.0.1", 10 | "react-dom": "^17.0.1", 11 | "react-router-dom": "^5.2.0", 12 | "react-scripts": "4.0.0", 13 | "web-vitals": "^0.2.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /navegacao/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/navegacao/public/favicon.ico -------------------------------------------------------------------------------- /navegacao/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
    32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /navegacao/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/navegacao/public/logo192.png -------------------------------------------------------------------------------- /navegacao/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/navegacao/public/logo512.png -------------------------------------------------------------------------------- /navegacao/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 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": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /navegacao/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /navegacao/src/components/layout/Content.css: -------------------------------------------------------------------------------- 1 | .Content { 2 | display: flex; 3 | flex-grow: 1; 4 | background-color: #cdcdcd; 5 | padding: 30px; 6 | } -------------------------------------------------------------------------------- /navegacao/src/components/layout/Content.jsx: -------------------------------------------------------------------------------- 1 | import './Content.css' 2 | import React from 'react' 3 | import { Switch, Route } from 'react-router-dom' 4 | 5 | import Home from '../../views/examples/Home' 6 | import Param from '../../views/examples/Param' 7 | import About from '../../views/examples/About' 8 | import NotFound from '../../views/examples/NotFound' 9 | 10 | const Content = props => ( 11 |
    12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
    27 | ) 28 | 29 | export default Content -------------------------------------------------------------------------------- /navegacao/src/components/layout/Menu.css: -------------------------------------------------------------------------------- 1 | .Menu { 2 | display: flex; 3 | flex-basis: 250px; 4 | 5 | background-color: #1e90ff; 6 | } 7 | 8 | .Menu nav { 9 | flex-grow: 1; 10 | } 11 | 12 | .Menu ul { 13 | list-style: none; 14 | padding: 0; 15 | } 16 | 17 | .Menu li { 18 | display: flex; 19 | } 20 | 21 | .Menu li a { 22 | flex: 1; 23 | padding: 10px; 24 | margin-bottom: 10px; 25 | 26 | text-decoration: none; 27 | color: #fff; 28 | font-size: 1.5rem; 29 | } 30 | 31 | .Menu li a:hover { 32 | background: #00000020; 33 | } -------------------------------------------------------------------------------- /navegacao/src/components/layout/Menu.jsx: -------------------------------------------------------------------------------- 1 | import './Menu.css' 2 | import React from 'react' 3 | 4 | import { Link } from 'react-router-dom' 5 | 6 | const Menu = props => ( 7 | 28 | ) 29 | 30 | export default Menu -------------------------------------------------------------------------------- /navegacao/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } -------------------------------------------------------------------------------- /navegacao/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import ReactDOM from 'react-dom' 3 | import React from 'react' 4 | 5 | import App from './views/App' 6 | 7 | ReactDOM.render( 8 | , 9 | document.getElementById('root') 10 | ) -------------------------------------------------------------------------------- /navegacao/src/views/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | display: flex; 3 | height: 100vh; 4 | } -------------------------------------------------------------------------------- /navegacao/src/views/App.jsx: -------------------------------------------------------------------------------- 1 | import './App.css' 2 | import React from 'react' 3 | import { BrowserRouter as Router } from 'react-router-dom' 4 | 5 | import Menu from '../components/layout/Menu' 6 | import Content from '../components/layout/Content' 7 | 8 | const App = props => ( 9 |
    10 | 11 | 12 | 13 | 14 |
    15 | ) 16 | 17 | export default App -------------------------------------------------------------------------------- /navegacao/src/views/examples/About.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const About = props => ( 4 |
    5 |

    Sobre

    6 |

    O nosso sistema foi criado...

    7 |
    8 | ) 9 | 10 | export default About -------------------------------------------------------------------------------- /navegacao/src/views/examples/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Home = props => ( 4 |
    5 |

    Início

    6 |

    Bem vindo!

    7 |
    8 | ) 9 | 10 | export default Home -------------------------------------------------------------------------------- /navegacao/src/views/examples/NotFound.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const NotFound = props => ( 4 |
    5 |

    404

    6 |

    Opssss... Página não encontrada!

    7 |
    8 | ) 9 | 10 | export default NotFound -------------------------------------------------------------------------------- /navegacao/src/views/examples/Param.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { useParams } from 'react-router-dom' 4 | 5 | const Param = props => { 6 | const { id } = useParams() 7 | return ( 8 |
    9 |

    Param

    10 |

    Valor: {id}!

    11 |
    12 | ) 13 | } 14 | 15 | export default Param -------------------------------------------------------------------------------- /novos-projetos/calculadora/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calculadora", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.4.0", 7 | "react-dom": "^16.4.0", 8 | "react-scripts": "1.1.4" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts start", 12 | "build": "react-scripts build", 13 | "test": "react-scripts test --env=jsdom", 14 | "eject": "react-scripts eject" 15 | } 16 | } -------------------------------------------------------------------------------- /novos-projetos/calculadora/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/novos-projetos/calculadora/public/favicon.ico -------------------------------------------------------------------------------- /novos-projetos/calculadora/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
    29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
    9 |
    10 | logo 11 |

    Welcome to React

    12 |
    13 |

    14 | To get started, edit src/App.js and save to reload. 15 |

    16 |
    17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/components/Button.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bg-button: #f0f0f0; 3 | --border-button: solid 1px #888; 4 | } 5 | 6 | .button { 7 | font-size: 1.4em; 8 | background-color: var(--bg-button); 9 | border: none; 10 | border-right: var(--border-button); 11 | border-bottom: var(--border-button); 12 | outline: none; 13 | } 14 | 15 | .button:active { 16 | background-color: #ccc; 17 | } 18 | 19 | .button.double { 20 | grid-column: span 2; 21 | } 22 | 23 | .button.triple { 24 | grid-column: span 3; 25 | } 26 | 27 | .button.operation { 28 | background-color: #fa8231; 29 | color: #FFF; 30 | } 31 | 32 | .button.operation:active { 33 | background-color: #fa8231cc; 34 | } -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/components/Button.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './Button.css' 3 | 4 | export default props => { 5 | let classes = 'button ' 6 | classes += props.operation ? 'operation' : '' 7 | classes += props.double ? 'double' : '' 8 | classes += props.triple ? 'triple' : '' 9 | 10 | return ( 11 | 16 | ) 17 | } -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/components/Display.css: -------------------------------------------------------------------------------- 1 | .display { 2 | grid-column: span 4; 3 | background-color: #0004; 4 | 5 | display: flex; 6 | justify-content: flex-end; 7 | align-items: center; 8 | padding: 20px; 9 | font-size: 2.1em; 10 | overflow: hidden; 11 | } -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/components/Display.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './Display.css' 3 | 4 | export default props => 5 |
    {props.value}
    -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/fonts/RobotoMono-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/novos-projetos/calculadora/src/fonts/RobotoMono-Thin.ttf -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/index.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'RobotoMono'; 3 | src: url('./fonts/RobotoMono-Thin.ttf'); 4 | } 5 | 6 | * { 7 | font-family: 'RobotoMono', monospace; 8 | } 9 | 10 | body { 11 | display: flex; 12 | height: 100vh; 13 | justify-content: center; 14 | align-items: center; 15 | text-align: center; 16 | 17 | color: #fff; 18 | background: linear-gradient(to right, rgb(83, 105, 118), rgb(41, 46, 73)); 19 | } -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import Calculator from './main/Calculator'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render( 8 |
    9 |

    Calculadora

    10 | 11 |
    12 | , document.getElementById('root')); 13 | registerServiceWorker(); 14 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /novos-projetos/calculadora/src/main/Calculator.css: -------------------------------------------------------------------------------- 1 | .calculator { 2 | height: 320px; 3 | width: 235px; 4 | border-radius: 5px; 5 | overflow: hidden; 6 | 7 | display: grid; 8 | grid-template-columns: repeat(4, 25%); 9 | grid-template-rows: 1fr 48px 48px 48px 48px 48px; 10 | } -------------------------------------------------------------------------------- /novos-projetos/crud/backend/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "users": [ 3 | { 4 | "id": 1, 5 | "name": "Arthur Oliveira", 6 | "email": "aoliveira@cod3r.com.br" 7 | }, 8 | { 9 | "id": 2, 10 | "name": "Maria Julia da Silva", 11 | "email": "mjds@empresa.com" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /novos-projetos/crud/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "json-server --watch db.json --port 3001" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "json-server": "0.13.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "axios": "0.18.0", 7 | "bootstrap": "4.1.1", 8 | "font-awesome": "4.7.0", 9 | "react-router": "4.2.0", 10 | "react-router-dom": "4.2.2", 11 | "react": "^16.4.0", 12 | "react-dom": "^16.4.0", 13 | "react-scripts": "1.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test --env=jsdom", 19 | "eject": "react-scripts eject" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/novos-projetos/crud/frontend/public/favicon.ico -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 23 | React App 24 | 25 | 26 | 29 |
    30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/assets/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/novos-projetos/crud/frontend/src/assets/imgs/logo.png -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/home/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Main from '../template/Main' 3 | 4 | export default props => 5 |
    7 |
    Bem Vindo!
    8 |
    9 |

    Sistema para exemplificar a construção 10 | de um cadastro desenvolvido em React!

    11 |
    -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Footer.css: -------------------------------------------------------------------------------- 1 | footer.footer { 2 | display: flex; 3 | align-items: center; 4 | justify-content: flex-end; 5 | padding: 0 25px; 6 | background-color: #FFF; 7 | box-shadow: var(--shadow); 8 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Footer.jsx: -------------------------------------------------------------------------------- 1 | import './Footer.css' 2 | import React from 'react' 3 | 4 | export default props => 5 |
    6 | 7 | Desenvolvido com por 8 | Cod3r 9 | 10 |
    -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Header.css: -------------------------------------------------------------------------------- 1 | header.header { 2 | background-color: #FFF; 3 | padding: 0px 15px; 4 | overflow: hidden; 5 | white-space: nowrap; 6 | box-shadow: var(--shadow); 7 | } 8 | 9 | header.header h1 { 10 | font-size: 1.8em; 11 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Header.jsx: -------------------------------------------------------------------------------- 1 | import './Header.css' 2 | import React from 'react' 3 | 4 | export default props => 5 |
    6 |

    7 | {props.title} 8 |

    9 |

    {props.subtitle}

    10 |
    -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Logo.css: -------------------------------------------------------------------------------- 1 | aside.logo { 2 | background-color: var(--bg-dark); 3 | display: flex; 4 | justify-content: center; 5 | align-items: center; 6 | } 7 | 8 | aside.logo img { 9 | padding: 0px 15px; 10 | width: 100%; 11 | } 12 | 13 | @media(max-width: 576px) { 14 | aside.logo img { 15 | width: 350px; 16 | } 17 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Logo.jsx: -------------------------------------------------------------------------------- 1 | import './Logo.css' 2 | import logo from '../../assets/imgs/logo.png' 3 | import React from 'react' 4 | import { Link } from 'react-router-dom' 5 | 6 | export default props => 7 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Main.css: -------------------------------------------------------------------------------- 1 | main > div { 2 | background-color: #FFF; 3 | box-shadow: 0px 0px 15px #0004; 4 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Main.jsx: -------------------------------------------------------------------------------- 1 | import './Main.css' 2 | import React from 'react' 3 | import Header from './Header' 4 | 5 | export default props => 6 | 7 |
    8 |
    9 |
    10 | {props.children} 11 |
    12 |
    13 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Nav.css: -------------------------------------------------------------------------------- 1 | aside.menu-area { 2 | background-color: var(--bg-dark); 3 | box-shadow: 4 | 2px 0 10px 0 rgba(0, 0, 0, 0.12), 5 | 2px 0 15px 0 rgba(0, 0, 0, 0.09); 6 | } 7 | 8 | .menu a { 9 | display: block; 10 | text-decoration: none; 11 | color: #FFF; 12 | font-weight: 300; 13 | padding: 15px; 14 | } 15 | 16 | .menu a:hover { 17 | background: linear-gradient(135deg, #07a7e3 0%, #32dac3 100%); 18 | } 19 | 20 | @media(max-width: 768px) { 21 | .menu { 22 | display: flex; 23 | justify-content: flex-start; 24 | align-items: center; 25 | } 26 | 27 | .menu a { 28 | display: inline; 29 | padding: 10px; 30 | margin: 0px; 31 | } 32 | 33 | .menu { 34 | height: 100%; 35 | justify-content: space-around; 36 | } 37 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/components/template/Nav.jsx: -------------------------------------------------------------------------------- 1 | import './Nav.css' 2 | import React from 'react' 3 | import { Link } from 'react-router-dom' 4 | 5 | export default props => 6 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './main/App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/main/App.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --bg-dark: #1A2F3A; 3 | 4 | --logo-height: 100px; 5 | --header-height: 100px; 6 | --menu-top-height: 70px; 7 | --aside-width: 225px; 8 | --footer-height: 40px; 9 | 10 | --shadow: 11 | 0 2px 23px 0 rgba(0, 0, 0, 0.1), 12 | 0 2px 49px 0 rgba(0, 0, 0, 0.06); 13 | } 14 | 15 | * { 16 | box-sizing: border-box; 17 | font-family: 'Montserrat', sans-serif; 18 | } 19 | 20 | /* Layout em Grid */ 21 | 22 | .app { 23 | margin: 0px; 24 | display: grid; 25 | grid-template-columns: var(--aside-width) 1fr; 26 | grid-template-rows: 27 | var(--header-height) 28 | 1fr 29 | var(--footer-height); 30 | grid-template-areas: 31 | "logo header" 32 | "menu content" 33 | "menu footer"; 34 | height: 100vh; 35 | background-color: #F5F5F5; 36 | } 37 | 38 | aside.logo { 39 | grid-area: logo; 40 | } 41 | 42 | header.header { 43 | grid-area: header; 44 | } 45 | 46 | aside.menu-area { 47 | grid-area: menu; 48 | } 49 | 50 | main.content { 51 | grid-area: content; 52 | } 53 | 54 | footer.footer { 55 | grid-area: footer; 56 | } 57 | 58 | @media(max-width: 768px) { 59 | .app { 60 | grid-template-rows: 61 | var(--header-height) 62 | var(--menu-top-height) 63 | 1fr 64 | var(--footer-height); 65 | grid-template-columns: var(--aside-width) 1fr; 66 | grid-template-areas: 67 | "logo header" 68 | "menu menu" 69 | "content content" 70 | "footer footer"; 71 | } 72 | } 73 | 74 | @media(max-width: 576px) { 75 | .app { 76 | grid-template-rows: 77 | var(--logo-height) 78 | var(--menu-top-height) 79 | 1fr 80 | var(--footer-height); 81 | grid-template-columns: 1fr; 82 | grid-template-areas: 83 | "logo" 84 | "menu" 85 | "content" 86 | "footer"; 87 | } 88 | } -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/main/App.jsx: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css' 2 | import 'font-awesome/css/font-awesome.min.css' 3 | import './App.css' 4 | import React from 'react' 5 | import { BrowserRouter } from 'react-router-dom' 6 | 7 | import Logo from '../components/template/Logo' 8 | import Nav from '../components/template/Nav' 9 | import Routes from './Routes' 10 | import Footer from '../components/template/Footer' 11 | 12 | export default props => 13 | 14 |
    15 | 16 |
    20 |
    -------------------------------------------------------------------------------- /novos-projetos/crud/frontend/src/main/Routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Switch, Route, Redirect } from 'react-router' 3 | 4 | import Home from '../components/home/Home' 5 | import UserCrud from '../components/user/UserCrud' 6 | 7 | export default props => 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /redux-simples/.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 | -------------------------------------------------------------------------------- /redux-simples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-simples", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.5.0", 8 | "@testing-library/user-event": "^7.2.1", 9 | "react": "^16.13.1", 10 | "react-dom": "^16.13.1", 11 | "react-redux": "^7.2.0", 12 | "react-scripts": "3.4.1", 13 | "redux": "^4.0.5" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": "react-app" 23 | }, 24 | "browserslist": { 25 | "production": [ 26 | ">0.2%", 27 | "not dead", 28 | "not op_mini all" 29 | ], 30 | "development": [ 31 | "last 1 chrome version", 32 | "last 1 firefox version", 33 | "last 1 safari version" 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /redux-simples/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/redux-simples/public/favicon.ico -------------------------------------------------------------------------------- /redux-simples/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
    32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /redux-simples/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/redux-simples/public/logo192.png -------------------------------------------------------------------------------- /redux-simples/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cod3rcursos/curso-react-redux/8df4d7192e0b3bbc31dc1534ccf29d23dc4f1e37/redux-simples/public/logo512.png -------------------------------------------------------------------------------- /redux-simples/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 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": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /redux-simples/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /redux-simples/src/App.css: -------------------------------------------------------------------------------- 1 | 2 | .App { 3 | display: flex; 4 | flex-direction: column; 5 | text-align: center; 6 | } 7 | 8 | h1 { 9 | font-weight: 200; 10 | } 11 | 12 | .linha { 13 | display: flex; 14 | } -------------------------------------------------------------------------------- /redux-simples/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | 4 | import Intervalo from './components/Intervalo' 5 | import Media from './components/Media'; 6 | import Soma from './components/Soma'; 7 | import Sorteio from './components/Sorteio'; 8 | 9 | function App() { 10 | 11 | return ( 12 |
    13 |

    Exercício React-Redux (Simples)

    14 |
    15 | 16 |
    17 |
    18 | 19 | 20 | 21 |
    22 |
    23 | ); 24 | } 25 | 26 | export default App; 27 | -------------------------------------------------------------------------------- /redux-simples/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /redux-simples/src/components/Card.css: -------------------------------------------------------------------------------- 1 | .Card { 2 | flex: 1; 3 | display: flex; 4 | flex-direction: column; 5 | margin: 5px; 6 | } 7 | 8 | .Card .Header { 9 | display: flex; 10 | justify-content: center; 11 | } 12 | 13 | .Card .Header .Title { 14 | flex: 1; 15 | padding: 5px; 16 | } 17 | 18 | .Card .Content { 19 | padding: 20px; 20 | } 21 | 22 | .Card.Red .Header { color: #FFF; background-color: #c62828; } 23 | .Card.Red .Content { background-color: #f44336; } 24 | 25 | .Card.Green .Header { color: #FFF; background-color: #2e7d32; } 26 | .Card.Green .Content { background-color: #4caf50; } 27 | 28 | .Card.Blue .Header { color: #FFF; background-color: #1565c0; } 29 | .Card.Blue .Content { background-color: #2196f3; } 30 | 31 | .Card.Purple .Header { color: #FFF; background-color: #6A1B9A; } 32 | .Card.Purple .Content { background-color: #9c27b0; } -------------------------------------------------------------------------------- /redux-simples/src/components/Card.jsx: -------------------------------------------------------------------------------- 1 | import './Card.css' 2 | import React from 'react' 3 | 4 | function getColor(props) { 5 | if(props.red) return "Red" 6 | if(props.green) return "Green" 7 | if(props.blue) return "Blue" 8 | if(props.purple) return "Purple" 9 | return "" 10 | } 11 | 12 | export default props => { 13 | return ( 14 |
    15 |
    16 | {props.title} 17 |
    18 |
    19 | {props.children} 20 |
    21 |
    22 | ) 23 | } -------------------------------------------------------------------------------- /redux-simples/src/components/Intervalo.css: -------------------------------------------------------------------------------- 1 | .Intervalo input { 2 | font-size: 1.8rem; 3 | margin-left: 20px; 4 | margin-right: 20px; 5 | width: 100px; 6 | } -------------------------------------------------------------------------------- /redux-simples/src/components/Intervalo.jsx: -------------------------------------------------------------------------------- 1 | import "./Intervalo.css"; 2 | import React from "react"; 3 | import { connect } from "react-redux"; 4 | 5 | import Card from "./Card"; 6 | import { alterarNumeroMinimo, alterarNumeroMaximo } from "../store/actions/numeros"; 7 | 8 | function Intervalo(props) { 9 | const { min, max } = props; 10 | 11 | return ( 12 | 13 |
    14 | 15 | Mínino: 16 | props.alterarMinimo(+e.target.value)} /> 18 | 19 | 20 | Máximo: 21 | props.alterarMaximo(+e.target.value)} /> 23 | 24 |
    25 |
    26 | ); 27 | } 28 | 29 | function mapStateToProps(state) { 30 | return { 31 | min: state.numeros.min, 32 | max: state.numeros.max, 33 | }; 34 | } 35 | 36 | function mapDispatchToProp(dispatch) { 37 | return { 38 | alterarMinimo(novoNumero) { 39 | // action creator -> action 40 | const action = alterarNumeroMinimo(novoNumero); 41 | dispatch(action); 42 | }, 43 | alterarMaximo(novoNumero) { 44 | // action creator -> action 45 | const action = alterarNumeroMaximo(novoNumero); 46 | dispatch(action); 47 | }, 48 | }; 49 | } 50 | 51 | export default connect( 52 | mapStateToProps, 53 | mapDispatchToProp 54 | )(Intervalo); 55 | -------------------------------------------------------------------------------- /redux-simples/src/components/Media.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { connect } from "react-redux"; 3 | 4 | import Card from "./Card"; 5 | 6 | function Media(props) { 7 | const { min, max } = props; 8 | console.log(props) 9 | return ( 10 | 11 |
    12 | 13 | Resultado: 14 | {(max + min) / 2} 15 | 16 |
    17 |
    18 | ); 19 | } 20 | 21 | function mapStateToProps(state) { 22 | return { 23 | min: state.numeros.min, 24 | max: state.numeros.max, 25 | }; 26 | } 27 | 28 | export default connect(mapStateToProps)(Media); 29 | -------------------------------------------------------------------------------- /redux-simples/src/components/Soma.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | import Card from './Card' 5 | 6 | function Soma(props) { 7 | const { min, max } = props 8 | return ( 9 | 10 |
    11 | 12 | Resultado: 13 | { max + min } 14 | 15 |
    16 |
    17 | ) 18 | } 19 | 20 | function mapStateToProp(state) { 21 | return { 22 | min: state.numeros.min, 23 | max: state.numeros.max, 24 | } 25 | } 26 | 27 | export default connect(mapStateToProp)(Soma) -------------------------------------------------------------------------------- /redux-simples/src/components/Sorteio.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { connect } from 'react-redux' 3 | 4 | import Card from "./Card"; 5 | 6 | function Sorteio(props) { 7 | const { min, max } = props; 8 | const aleatorio = parseInt(Math.random() * (max - min)) + min; 9 | return ( 10 | 11 |
    12 | 13 | Resultado: 14 | {aleatorio} 15 | 16 |
    17 |
    18 | ); 19 | } 20 | 21 | function mapStateToProp(state) { 22 | return { 23 | min: state.numeros.min, 24 | max: state.numeros.max, 25 | }; 26 | } 27 | 28 | export default connect(mapStateToProp)(Sorteio); 29 | -------------------------------------------------------------------------------- /redux-simples/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #222; 3 | font-size: 2rem; 4 | font-family: Oswald; 5 | color: #FFF; 6 | margin: 30px; 7 | } -------------------------------------------------------------------------------- /redux-simples/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | import { Provider } from 'react-redux' 8 | import configStore from './store/storeConfig' 9 | 10 | const store = configStore() 11 | 12 | ReactDOM.render( 13 | 14 | 15 | 16 | 17 | , 18 | document.getElementById('root') 19 | ); 20 | 21 | // If you want your app to work offline and load faster, you can change 22 | // unregister() to register() below. Note this comes with some pitfalls. 23 | // Learn more about service workers: https://bit.ly/CRA-PWA 24 | serviceWorker.unregister(); 25 | -------------------------------------------------------------------------------- /redux-simples/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /redux-simples/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/extend-expect'; 6 | -------------------------------------------------------------------------------- /redux-simples/src/store/actions/actionTypes.js: -------------------------------------------------------------------------------- 1 | export const NUM_MIN_ALTERADO = 'NUM_MIN_ALTERADO' 2 | export const NUM_MAX_ALTERADO = 'NUM_MAX_ALTERADO' -------------------------------------------------------------------------------- /redux-simples/src/store/actions/numeros.js: -------------------------------------------------------------------------------- 1 | import { 2 | NUM_MIN_ALTERADO, 3 | NUM_MAX_ALTERADO 4 | } from './actionTypes' 5 | 6 | // Action Creator 7 | export function alterarNumeroMinimo(novoNumero) { 8 | return { 9 | type: NUM_MIN_ALTERADO, 10 | payload: novoNumero 11 | } 12 | } 13 | 14 | // Action Creator 15 | export function alterarNumeroMaximo(novoNumero) { 16 | return { 17 | type: NUM_MAX_ALTERADO, 18 | payload: novoNumero 19 | } 20 | } -------------------------------------------------------------------------------- /redux-simples/src/store/reducers/numeros.js: -------------------------------------------------------------------------------- 1 | import { 2 | NUM_MIN_ALTERADO, 3 | NUM_MAX_ALTERADO 4 | } from '../actions/actionTypes' 5 | 6 | const initialState = { 7 | min: 1, 8 | max: 10 9 | } 10 | 11 | export default function(state = initialState, action) { 12 | switch(action.type) { 13 | case NUM_MIN_ALTERADO: 14 | return { 15 | ...state, 16 | min: action.payload 17 | } 18 | case NUM_MAX_ALTERADO: 19 | return { 20 | ...state, 21 | max: action.payload 22 | } 23 | default: 24 | return state 25 | } 26 | } -------------------------------------------------------------------------------- /redux-simples/src/store/storeConfig.js: -------------------------------------------------------------------------------- 1 | import { createStore, combineReducers } from 'redux' 2 | 3 | import numerosReducer from './reducers/numeros' 4 | 5 | const reducers = combineReducers({ 6 | numeros: numerosReducer, 7 | }) 8 | 9 | function storeConfig() { 10 | return createStore(reducers) 11 | } 12 | 13 | export default storeConfig -------------------------------------------------------------------------------- /todo-app/backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /todo-app/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/loader.js", 6 | "scripts": { 7 | "dev": "nodemon", 8 | "production": "pm2 start src/loader.js --name todo-app" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "body-parser": "^1.15.2", 15 | "express": "^4.14.0", 16 | "mongoose": "^4.7.0", 17 | "node-restful": "^0.2.5", 18 | "nodemon": "^1.11.0", 19 | "pm2": "^2.1.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /todo-app/backend/src/api/todo/todo.js: -------------------------------------------------------------------------------- 1 | const restful = require('node-restful') 2 | const mongoose = restful.mongoose 3 | 4 | const todoSchema = new mongoose.Schema({ 5 | description: { type: String, required: true }, 6 | done: { type: Boolean, required: true, default: false }, 7 | createdAt: { type: Date, default: Date.now } 8 | }) 9 | 10 | module.exports = restful.model('Todo', todoSchema) -------------------------------------------------------------------------------- /todo-app/backend/src/api/todo/todoService.js: -------------------------------------------------------------------------------- 1 | const Todo = require('./todo') 2 | 3 | Todo.methods(['get', 'post', 'put', 'delete']) 4 | Todo.updateOptions({new: true, runValidators: true}) 5 | 6 | module.exports = Todo -------------------------------------------------------------------------------- /todo-app/backend/src/config/cors.js: -------------------------------------------------------------------------------- 1 | module.exports = function(req, res, next) { 2 | res.header('Access-Control-Allow-Origin', '*') 3 | res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE') 4 | res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept') 5 | next() 6 | } -------------------------------------------------------------------------------- /todo-app/backend/src/config/database.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | mongoose.Promise = global.Promise 3 | module.exports = mongoose.connect('mongodb://localhost/todo') -------------------------------------------------------------------------------- /todo-app/backend/src/config/routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | 3 | module.exports = function(server) { 4 | 5 | // API Routes 6 | const router = express.Router() 7 | server.use('/api', router) 8 | 9 | // TODO Routes 10 | const todoService = require('../api/todo/todoService') 11 | todoService.register(router, '/todos') 12 | } -------------------------------------------------------------------------------- /todo-app/backend/src/config/server.js: -------------------------------------------------------------------------------- 1 | const port = 3003 2 | 3 | const bodyParser = require('body-parser') 4 | const express = require('express') 5 | const server = express() 6 | const allowCors = require('./cors') 7 | 8 | server.use(bodyParser.urlencoded({ extended: true })) 9 | server.use(bodyParser.json()) 10 | server.use(allowCors) 11 | 12 | server.listen(port, function() { 13 | console.log(`BACKEND is running on port ${port}.`) 14 | }) 15 | 16 | module.exports = server -------------------------------------------------------------------------------- /todo-app/backend/src/loader.js: -------------------------------------------------------------------------------- 1 | const server = require('./config/server') 2 | require('./config/database') 3 | require('./config/routes')(server) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --progress --colors --inline --hot", 8 | "production": "webpack --progress -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "axios": "^0.15.3", 15 | "babel-core": "^6.22.1", 16 | "babel-loader": "^6.2.10", 17 | "babel-plugin-react-html-attrs": "^2.0.0", 18 | "babel-plugin-transform-object-rest-spread": "^6.22.0", 19 | "babel-preset-es2015": "^6.22.0", 20 | "babel-preset-react": "^6.22.0", 21 | "bootstrap": "^3.3.7", 22 | "css-loader": "^0.26.1", 23 | "extract-text-webpack-plugin": "^1.0.1", 24 | "file-loader": "^0.9.0", 25 | "font-awesome": "^4.7.0", 26 | "react": "^15.4.2", 27 | "react-dom": "^15.4.2", 28 | "react-router": "^3.0.2", 29 | "style-loader": "^0.13.1", 30 | "webpack": "^1.14.0", 31 | "webpack-dev-server": "^1.16.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Todo App 7 | 8 | 9 | 10 |
    11 | 12 | 13 | -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/about/about.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PageHeader from '../template/pageHeader' 3 | 4 | export default props => ( 5 |
    6 | 7 | 8 |

    Nossa História

    9 |

    Lorem ipsum dolor sit amet...

    10 |

    Missão e Visão

    11 |

    Lorem ipsum dolor sit amet...

    12 |

    Imprensa

    13 |

    Lorem ipsum dolor sit amet...

    14 |
    15 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './main/app' 4 | 5 | ReactDOM.render(, document.getElementById('app')) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/main/app.jsx: -------------------------------------------------------------------------------- 1 | import 'modules/bootstrap/dist/css/bootstrap.min.css' 2 | import 'modules/font-awesome/css/font-awesome.min.css' 3 | import '../template/custom.css' 4 | 5 | import React from 'react' 6 | import Menu from '../template/menu' 7 | import Routes from './routes' 8 | 9 | export default props => ( 10 |
    11 | 12 | 13 |
    14 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/main/routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Router, Route, Redirect, hashHistory } from 'react-router' 3 | 4 | import Todo from '../todo/todo' 5 | import About from '../about/about' 6 | 7 | export default props => ( 8 | 9 | 10 | 11 | 12 | 13 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/custom.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | margin-right: 5px; 3 | } 4 | 5 | .markedAsDone { 6 | text-decoration: line-through; 7 | color: #777; 8 | } 9 | 10 | .tableActions { 11 | width: 105px; 12 | } 13 | 14 | .todoForm { 15 | padding-bottom: 60px; 16 | } -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/grid.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Grid extends Component { 4 | toCssClasses(numbers) { 5 | const cols = numbers ? numbers.split(' ') : [] 6 | let classes = '' 7 | 8 | if(cols[0]) classes += `col-xs-${cols[0]}` 9 | if(cols[1]) classes += ` col-sm-${cols[1]}` 10 | if(cols[2]) classes += ` col-md-${cols[2]}` 11 | if(cols[3]) classes += ` col-lg-${cols[3]}` 12 | 13 | return classes 14 | } 15 | 16 | render() { 17 | const gridClasses = this.toCssClasses(this.props.cols || 12) 18 | return ( 19 |
    20 | {this.props.children} 21 |
    22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/iconButton.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import If from './if' 3 | 4 | export default props => ( 5 | 6 | 10 | 11 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/if.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | if(props.test) { 5 | return props.children 6 | } else { 7 | return false 8 | } 9 | } -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/menu.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 | 20 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/template/pageHeader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 |

    {props.name} {props.small}

    6 |
    7 | ) -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/todo/todoForm.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Grid from '../template/grid' 3 | import IconButton from '../template/iconButton' 4 | 5 | export default props => { 6 | const keyHandler = (e) => { 7 | if (e.key === 'Enter') { 8 | e.shiftKey ? props.handleSearch() : props.handleAdd() 9 | } else if (e.key === 'Escape') { 10 | props.handleClear() 11 | } 12 | } 13 | 14 | return ( 15 |
    16 | 17 | 22 | 23 | 24 | 26 | 28 | 30 | 31 |
    32 | ) 33 | } -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/src/todo/todoList.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import IconButton from '../template/iconButton' 3 | 4 | export default props => { 5 | 6 | const renderRows = () => { 7 | const list = props.list || [] 8 | return list.map(todo => ( 9 | 10 | {todo.description} 11 | 12 | props.handleMarkAsDone(todo)}> 14 | props.handleMarkAsPending(todo)}> 16 | props.handleRemove(todo)}> 18 | 19 | 20 | )) 21 | } 22 | 23 | return ( 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {renderRows()} 33 | 34 |
    DescriçãoAções
    35 | ) 36 | } -------------------------------------------------------------------------------- /todo-app/frontend-sem-redux/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 3 | 4 | module.exports = { 5 | entry: './src/index.jsx', 6 | output: { 7 | path: __dirname + '/public', 8 | filename: './app.js' 9 | }, 10 | devServer: { 11 | port: 8080, 12 | contentBase: './public', 13 | }, 14 | resolve: { 15 | extensions: ['', '.js', '.jsx'], 16 | alias: { 17 | modules: __dirname + '/node_modules' 18 | } 19 | }, 20 | plugins: [ 21 | new ExtractTextPlugin('app.css') 22 | ], 23 | module: { 24 | loaders: [{ 25 | test: /.js[x]?$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/, 28 | query: { 29 | presets: ['es2015', 'react'], 30 | plugins: ['transform-object-rest-spread'] 31 | } 32 | }, { 33 | test: /\.css$/, 34 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 35 | }, { 36 | test: /\.woff|.woff2|.ttf|.eot|.svg*.*$/, 37 | loader: 'file' 38 | }] 39 | } 40 | } -------------------------------------------------------------------------------- /todo-app/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log -------------------------------------------------------------------------------- /todo-app/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack-dev-server --progress --colors --inline --hot", 8 | "production": "webpack --progress -p" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "axios": "^0.15.3", 15 | "babel-core": "^6.22.1", 16 | "babel-loader": "^6.2.10", 17 | "babel-plugin-react-html-attrs": "^2.0.0", 18 | "babel-plugin-transform-object-rest-spread": "^6.22.0", 19 | "babel-preset-es2015": "^6.22.0", 20 | "babel-preset-react": "^6.22.0", 21 | "bootstrap": "^3.3.7", 22 | "css-loader": "^0.26.1", 23 | "extract-text-webpack-plugin": "^1.0.1", 24 | "file-loader": "^0.9.0", 25 | "font-awesome": "^4.7.0", 26 | "react": "^15.4.2", 27 | "react-dom": "^15.4.2", 28 | "react-redux": "^5.0.2", 29 | "react-router": "^3.0.2", 30 | "redux": "^3.6.0", 31 | "redux-multi": "^0.1.12", 32 | "redux-promise": "^0.5.3", 33 | "redux-thunk": "^2.2.0", 34 | "style-loader": "^0.13.1", 35 | "webpack": "^1.14.0", 36 | "webpack-dev-server": "^1.16.2" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /todo-app/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Todo App 7 | 8 | 9 | 10 |
    11 | 12 | 13 | -------------------------------------------------------------------------------- /todo-app/frontend/src/about/about.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PageHeader from '../template/pageHeader' 3 | 4 | export default props => ( 5 |
    6 | 7 | 8 |

    Nossa História

    9 |

    Lorem ipsum dolor sit amet...

    10 |

    Missão e Visão

    11 |

    Lorem ipsum dolor sit amet...

    12 |

    Imprensa

    13 |

    Lorem ipsum dolor sit amet...

    14 |
    15 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { applyMiddleware, createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | 6 | import promise from 'redux-promise' 7 | import multi from 'redux-multi' 8 | import thunk from 'redux-thunk' 9 | 10 | import App from './main/app' 11 | import reducers from './main/reducers' 12 | 13 | const devTools = window.__REDUX_DEVTOOLS_EXTENSION__ 14 | && window.__REDUX_DEVTOOLS_EXTENSION__() 15 | const store = applyMiddleware(thunk, multi, promise)(createStore)(reducers, devTools) 16 | ReactDOM.render( 17 | 18 | 19 | 20 | , document.getElementById('app')) -------------------------------------------------------------------------------- /todo-app/frontend/src/main/app.jsx: -------------------------------------------------------------------------------- 1 | import 'modules/bootstrap/dist/css/bootstrap.min.css' 2 | import 'modules/font-awesome/css/font-awesome.min.css' 3 | import '../template/custom.css' 4 | 5 | import React from 'react' 6 | import Menu from '../template/menu' 7 | import Routes from './routes' 8 | 9 | export default props => ( 10 |
    11 | 12 | 13 |
    14 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/main/reducers.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import todoReducer from '../todo/todoReducer' 3 | 4 | const rootReducer = combineReducers({ 5 | todo: todoReducer 6 | }) 7 | 8 | export default rootReducer -------------------------------------------------------------------------------- /todo-app/frontend/src/main/routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Router, Route, Redirect, hashHistory } from 'react-router' 3 | 4 | import Todo from '../todo/todo' 5 | import About from '../about/about' 6 | 7 | export default props => ( 8 | 9 | 10 | 11 | 12 | 13 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/template/custom.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | margin-right: 5px; 3 | } 4 | 5 | .markedAsDone { 6 | text-decoration: line-through; 7 | color: #777; 8 | } 9 | 10 | .tableActions { 11 | width: 105px; 12 | } 13 | 14 | .todoForm { 15 | padding-bottom: 60px; 16 | } -------------------------------------------------------------------------------- /todo-app/frontend/src/template/grid.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Grid extends Component { 4 | toCssClasses(numbers) { 5 | const cols = numbers ? numbers.split(' ') : [] 6 | let classes = '' 7 | 8 | if(cols[0]) classes += `col-xs-${cols[0]}` 9 | if(cols[1]) classes += ` col-sm-${cols[1]}` 10 | if(cols[2]) classes += ` col-md-${cols[2]}` 11 | if(cols[3]) classes += ` col-lg-${cols[3]}` 12 | 13 | return classes 14 | } 15 | 16 | render() { 17 | const gridClasses = this.toCssClasses(this.props.cols || 12) 18 | return ( 19 |
    20 | {this.props.children} 21 |
    22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /todo-app/frontend/src/template/iconButton.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import If from './if' 3 | 4 | export default props => ( 5 | 6 | 10 | 11 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/template/if.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => { 4 | if(props.test) { 5 | return props.children 6 | } else { 7 | return false 8 | } 9 | } -------------------------------------------------------------------------------- /todo-app/frontend/src/template/menu.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 | 20 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/template/pageHeader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default props => ( 4 |
    5 |

    {props.name} {props.small}

    6 |
    7 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/todo/todo.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import PageHeader from '../template/pageHeader' 4 | import TodoForm from './todoForm' 5 | import TodoList from './todoList' 6 | 7 | export default props => ( 8 |
    9 | 10 | 11 | 12 |
    13 | ) -------------------------------------------------------------------------------- /todo-app/frontend/src/todo/todoActions.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | const URL = 'http://localhost:3003/api/todos' 4 | 5 | export const changeDescription = event => ({ 6 | type: 'DESCRIPTION_CHANGED', 7 | payload: event.target.value 8 | }) 9 | 10 | export const search = () => { 11 | return (dispatch, getState) => { 12 | const description = getState().todo.description 13 | const search = description ? `&description__regex=/${description}/` : '' 14 | const request = axios.get(`${URL}?sort=-createdAt${search}`) 15 | .then(resp => dispatch({type: 'TODO_SEARCHED', payload: resp.data})) 16 | } 17 | } 18 | 19 | export const add = (description) => { 20 | return dispatch => { 21 | axios.post(URL, { description }) 22 | .then(resp => dispatch(clear())) 23 | .then(resp => dispatch(search())) 24 | } 25 | } 26 | 27 | export const markAsDone = (todo) => { 28 | return dispatch => { 29 | axios.put(`${URL}/${todo._id}`, { ...todo, done: true }) 30 | .then(resp => dispatch(search())) 31 | } 32 | } 33 | 34 | export const markAsPending = (todo) => { 35 | return dispatch => { 36 | axios.put(`${URL}/${todo._id}`, { ...todo, done: false }) 37 | .then(resp => dispatch(search())) 38 | } 39 | } 40 | 41 | export const remove = (todo) => { 42 | return dispatch => { 43 | axios.delete(`${URL}/${todo._id}`) 44 | .then(resp => dispatch(search())) 45 | } 46 | } 47 | 48 | export const clear = () => { 49 | return [{ type: 'TODO_CLEAR' }, search()] 50 | } -------------------------------------------------------------------------------- /todo-app/frontend/src/todo/todoForm.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { bindActionCreators } from 'redux' 4 | 5 | import Grid from '../template/grid' 6 | import IconButton from '../template/iconButton' 7 | import { add, changeDescription, search, clear } from './todoActions' 8 | 9 | class TodoForm extends Component { 10 | constructor(props) { 11 | super(props) 12 | this.keyHandler = this.keyHandler.bind(this) 13 | } 14 | 15 | componentWillMount() { 16 | this.props.search() 17 | } 18 | 19 | keyHandler(e) { 20 | const { add, clear, search, description } = this.props 21 | if (e.key === 'Enter') { 22 | e.shiftKey ? search() : add(description) 23 | } else if (e.key === 'Escape') { 24 | clear() 25 | } 26 | } 27 | 28 | render() { 29 | const { add, search, description } = this.props 30 | return ( 31 |
    32 | 33 | 38 | 39 | 40 | add(description)}> 42 | 44 | 46 | 47 |
    48 | ) 49 | } 50 | } 51 | 52 | const mapStateToProps = state => ({description: state.todo.description}) 53 | const mapDispatchToProps = dispatch => 54 | bindActionCreators({ add, changeDescription, search, clear }, dispatch) 55 | export default connect(mapStateToProps, mapDispatchToProps)(TodoForm) -------------------------------------------------------------------------------- /todo-app/frontend/src/todo/todoList.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | import { bindActionCreators } from 'redux' 4 | 5 | import IconButton from '../template/iconButton' 6 | import { markAsDone, markAsPending, remove } from './todoActions' 7 | 8 | const TodoList = props => { 9 | 10 | const renderRows = () => { 11 | const list = props.list || [] 12 | return list.map(todo => ( 13 | 14 | {todo.description} 15 | 16 | props.markAsDone(todo)}> 18 | props.markAsPending(todo)}> 20 | props.remove(todo)}> 22 | 23 | 24 | )) 25 | } 26 | 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {renderRows()} 37 | 38 |
    DescriçãoAções
    39 | ) 40 | } 41 | 42 | const mapStateToProps = state => ({list: state.todo.list}) 43 | const mapDispatchToProps = dispatch => 44 | bindActionCreators({ markAsDone, markAsPending, remove }, dispatch) 45 | export default connect(mapStateToProps, mapDispatchToProps)(TodoList) -------------------------------------------------------------------------------- /todo-app/frontend/src/todo/todoReducer.js: -------------------------------------------------------------------------------- 1 | const INITIAL_STATE = { description: '', list: [] } 2 | 3 | export default (state = INITIAL_STATE, action) => { 4 | switch(action.type) { 5 | case 'DESCRIPTION_CHANGED': 6 | return { ...state, description: action.payload } 7 | case 'TODO_SEARCHED': 8 | return { ...state, list: action.payload } 9 | case 'TODO_CLEAR': 10 | return { ...state, description: '' } 11 | default: 12 | return state 13 | } 14 | } -------------------------------------------------------------------------------- /todo-app/frontend/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 3 | 4 | module.exports = { 5 | entry: './src/index.jsx', 6 | output: { 7 | path: __dirname + '/public', 8 | filename: './app.js' 9 | }, 10 | devServer: { 11 | port: 8080, 12 | contentBase: './public', 13 | }, 14 | resolve: { 15 | extensions: ['', '.js', '.jsx'], 16 | alias: { 17 | modules: __dirname + '/node_modules' 18 | } 19 | }, 20 | plugins: [ 21 | new ExtractTextPlugin('app.css') 22 | ], 23 | module: { 24 | loaders: [{ 25 | test: /.js[x]?$/, 26 | loader: 'babel-loader', 27 | exclude: /node_modules/, 28 | query: { 29 | presets: ['es2015', 'react'], 30 | plugins: ['transform-object-rest-spread'] 31 | } 32 | }, { 33 | test: /\.css$/, 34 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 35 | }, { 36 | test: /\.woff|.woff2|.ttf|.eot|.svg*.*$/, 37 | loader: 'file' 38 | }] 39 | } 40 | } --------------------------------------------------------------------------------