├── .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 |
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 |
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 |
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 |
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 |
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 | Id |
26 | Nome |
27 | Preço |
28 |
29 |
30 |
31 | {getLinhas()}
32 |
33 |
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 |
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 |
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 |
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 | Nome |
38 | Mês |
39 | Ano |
40 | Ações |
41 |
42 |
43 |
44 | {this.renderRows()}
45 |
46 |
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 |
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 |
7 | )
--------------------------------------------------------------------------------
/my-money-app/frontend/src/common/template/content.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default props => (
4 |
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 |
10 | )
--------------------------------------------------------------------------------
/my-money-app/frontend/src/common/template/header.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default props => (
4 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------
/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 |
17 |
18 |
19 |
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 |
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 | Descrição |
28 | Ações |
29 |
30 |
31 |
32 | {renderRows()}
33 |
34 |
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 |
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 | Descrição |
32 | Ações |
33 |
34 |
35 |
36 | {renderRows()}
37 |
38 |
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 | }
--------------------------------------------------------------------------------