├── .cache └── 325c8f456729b912b0d2134054eb7448-dfeeb2271cc2857eb0a45a5003c8bbee ├── .gitignore ├── .storybook └── config.js ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── apis ├── login.api.js ├── postit.api.js └── signup.api.js ├── components ├── alert │ ├── alert.css │ ├── alert.js │ ├── alert.stories.js │ └── index.js ├── container │ ├── container.css │ ├── container.js │ ├── container.stories.js │ └── index.js ├── form │ ├── button │ │ ├── button.css │ │ ├── button.js │ │ ├── button.stories.js │ │ └── index.js │ ├── form.css │ ├── form.js │ ├── form.stories.js │ ├── index.js │ ├── input │ │ ├── index.js │ │ ├── input.css │ │ ├── input.js │ │ ├── input.stories.js │ │ └── input2.js │ ├── label │ │ ├── index.js │ │ ├── label.css │ │ ├── label.js │ │ └── label.stories.js │ └── link │ │ ├── index.js │ │ ├── link.css │ │ ├── link.js │ │ └── link.stories.js ├── navbar │ ├── index.js │ ├── logo-reprograma.png │ ├── menu │ │ ├── index.js │ │ ├── menu.css │ │ ├── menu.js │ │ └── menu.stories.js │ ├── navbar.css │ ├── navbar.js │ └── navbar.stories.js └── postit │ ├── index.js │ ├── postit.css │ ├── postit.js │ └── postit.stories.js ├── index.css ├── index.js ├── infra ├── api-config.js └── local-storage.js ├── logo.svg ├── pages ├── home │ ├── home.css │ ├── home.js │ ├── home.stories.js │ └── index.js ├── login │ ├── index.js │ ├── login.js │ └── login.stories.js ├── pageNotFound │ ├── index.js │ ├── notFound.jpeg │ ├── pageNotFound.css │ └── pageNotFound.js └── signup │ ├── index.js │ ├── signup.js │ └── signup.stories.js └── serviceWorker.js /.cache/325c8f456729b912b0d2134054eb7448-dfeeb2271cc2857eb0a45a5003c8bbee: -------------------------------------------------------------------------------- 1 | {"value":{"success":true,"data":{"latest":{"version":"4.0.0","info":{"plain":"- upgrade webpack & babel to latest\n- new addParameters and third argument to .add to pass data to addons\n- added the ability to theme storybook\n- improved ui for mobile devices\n- improved performance of addon-knobs"}}},"time":1542980441431},"type":"Object"} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import { configure } from '@storybook/react'; 2 | 3 | const req = require.context('../src', true, /\.stories\.js$/) 4 | 5 | function loadStories() { 6 | req.keys().forEach((filename) => req(filename)) 7 | } 8 | 9 | configure(loadStories, module); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Todo List React

2 | 3 | Guia para Front End Developers 4 | 5 | https://frontendmasters.com/books/front-end-handbook/2018/learning/internet.html 6 | 7 |

Criar Projeto React do Zero

8 | 9 | https://reactjs.org/docs/create-a-new-react-app.html 10 | 11 |

Links das Documentações:

12 | 13 | 14 | Lib de Componentes React 15 | 16 | https://material-ui.com/ 17 | 18 | React Doc 19 | 20 | https://reactjs.org/ 21 | 22 | 23 | EMS6 Resumo 24 | 25 | http://es6-features.org/#Constants 26 | 27 | MDN- DOc HTMl,CSS e Javascript 28 | 29 | https://developer.mozilla.org/pt-BR/docs/Web/JavaScript 30 | 31 | Babel 32 | 33 | https://babeljs.io/repl 34 | 35 | Storybook 36 | 37 | https://storybook.js.org/basics/guide-react/ 38 | 39 | Axios Instance 40 | 41 | https://github.com/axios/axios 42 | 43 | React Router 44 | 45 | https://reacttraining.com/react-router/web/api/Link 46 | 47 | Deploy da API gratuitamente 48 | 49 | https://app.netlify.com/ 50 | 51 | Deploy de APIS 52 | 53 | https://www.heroku.com/ 54 | 55 | Resumo de Map,Filter e Reduce 56 | 57 | http://desenvolvimentoparaweb.com/javascript/map-filter-reduce-javascript/ 58 | 59 | 60 |

Documentação da API usada

61 | 62 | https://lehtodoapi.herokuapp.com/api-docs 63 | 64 | 65 |

Livros e Cursos

66 | 67 | Clean Code - Livro 68 | 69 | https://www.amazon.com.br/C%C3%B3digo-limpo-Robert-C-Martin/dp/8576082675/ref=sr_1_1?ie=UTF8&qid=1542661633&sr=8-1&keywords=clean+codehttps://br.udacity.com/course/object-oriented-javascript--ud015 70 | 71 | Javascript Orientado a Objetos(curso gratuito) 72 | 73 | https://br.udacity.com/course/object-oriented-javascript--ud015 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.5.1", 7 | "@storybook/addon-actions": "^4.0.6", 8 | "@storybook/addon-links": "^4.0.6", 9 | "@storybook/addon-notes": "^4.0.6", 10 | "@storybook/addons": "^4.0.6", 11 | "axios": "^0.18.0", 12 | "react": "^16.6.1", 13 | "react-dom": "^16.6.1", 14 | "react-icons": "^3.2.2", 15 | "react-router": "^4.3.1", 16 | "react-router-dom": "^4.3.1", 17 | "react-scripts": "2.1.1", 18 | "storybook-react-router": "^1.0.1" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "storybook": "start-storybook -p 9001 -c .storybook", 25 | "eject": "react-scripts eject" 26 | }, 27 | "eslintConfig": { 28 | "extends": "react-app" 29 | }, 30 | "browserslist": [ 31 | ">0.2%", 32 | "not dead", 33 | "not ie <= 11", 34 | "not op_mini all" 35 | ], 36 | "devDependencies": { 37 | "@storybook/react": "^4.0.6" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reprograma/t6-react-todo-list/9c2da5e20c61c795014740138905bb58d08b7f10/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /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": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | } 9 | 10 | .App-header { 11 | background-color: #282c34; 12 | min-height: 100vh; 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | justify-content: center; 17 | font-size: calc(10px + 2vmin); 18 | color: white; 19 | } 20 | 21 | .App-link { 22 | color: #61dafb; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { 27 | transform: rotate(0deg); 28 | } 29 | to { 30 | transform: rotate(360deg); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Route, Switch } from 'react-router-dom' 3 | import { withRouter } from 'react-router' 4 | import Login from './pages/login' 5 | import Signup from './pages/signup' 6 | import Home from './pages/home' 7 | import Navbar from './components/navbar' 8 | import PageNotFound from './pages/pageNotFound' 9 | import { startServer } from './infra/api-config' 10 | import Alert from './components/alert' 11 | import { getUser } from './infra/local-storage' 12 | 13 | class App extends Component { 14 | constructor(props){ 15 | super(props) 16 | this.state = { 17 | openAlert : false, 18 | childrenAlert : '' 19 | } 20 | this.user = '' 21 | } 22 | showAlert= (message) =>{ 23 | this.setState({ 24 | openAlert : true, 25 | childrenAlert : message 26 | }) 27 | } 28 | closeAlert = () =>{ 29 | this.setState({ 30 | openAlert : false, 31 | childrenAlert : '' 32 | }) 33 | } 34 | componentDidMount() { 35 | startServer() 36 | //this.user = getUser() 37 | } 38 | 39 | render() { 40 | this.user = getUser() 41 | return ( 42 | 43 | 44 | 45 | 46 | }/> 47 | } /> 48 | 49 | 50 | {this.state.childrenAlert} 51 | 52 | 53 | ) 54 | } 55 | } 56 | 57 | export default withRouter(App) 58 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/apis/login.api.js: -------------------------------------------------------------------------------- 1 | import api from '../infra/api-config' 2 | 3 | export function loginUser(user){ 4 | const url = '/users/login' 5 | 6 | const data = { 7 | email : user.email, 8 | password: user.password 9 | } 10 | 11 | return api().post(url,data) 12 | 13 | } -------------------------------------------------------------------------------- /src/apis/postit.api.js: -------------------------------------------------------------------------------- 1 | import api from '../infra/api-config' 2 | 3 | export function createPostit(postit){ 4 | const url = '/todo' 5 | 6 | const data = { 7 | title : postit.title, 8 | desc : postit.text, 9 | color: postit.color 10 | } 11 | 12 | return api().post(url, data) 13 | } 14 | export function getPostitsApi(){ 15 | 16 | const url = '/todo' 17 | 18 | return api().get(url) 19 | } 20 | 21 | export function deletePostit(idPostit){ 22 | const url = `/todo/${idPostit}` 23 | 24 | return api().delete(url) 25 | } 26 | 27 | export function updatePostitApi(postit){ 28 | const url = `/todo/${postit.id}` 29 | 30 | const data = { 31 | title : postit.title, 32 | desc : postit.text, 33 | color: postit.color 34 | } 35 | 36 | return api().put(url,data) 37 | 38 | } -------------------------------------------------------------------------------- /src/apis/signup.api.js: -------------------------------------------------------------------------------- 1 | import api from '../infra/api-config' 2 | 3 | function signupUser(user){ 4 | const url = '/users' 5 | 6 | const data = { 7 | name : user.name, 8 | email: user.email, 9 | phone: user.phone, 10 | password: user.password 11 | } 12 | 13 | return api().post(url,data) 14 | 15 | } 16 | 17 | export default signupUser -------------------------------------------------------------------------------- /src/components/alert/alert.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reprograma/t6-react-todo-list/9c2da5e20c61c795014740138905bb58d08b7f10/src/components/alert/alert.css -------------------------------------------------------------------------------- /src/components/alert/alert.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Dialog from '@material-ui/core/Dialog' 3 | import DialogTitle from '@material-ui/core/DialogTitle' 4 | import Button from '@material-ui/core/Button' 5 | 6 | const Alert = (props) => { 7 | return ( 8 | 9 | {props.children} 10 | 11 | 12 | ) 13 | } 14 | 15 | export default Alert -------------------------------------------------------------------------------- /src/components/alert/alert.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Alert from './index' 4 | 5 | storiesOf('Components/Alert', module) 6 | .add('default', () =>( 7 | Email e Senha não cadastrados! 8 | )) 9 | -------------------------------------------------------------------------------- /src/components/alert/index.js: -------------------------------------------------------------------------------- 1 | import Alert from './alert' 2 | 3 | export default Alert -------------------------------------------------------------------------------- /src/components/container/container.css: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: 0.75rem 1rem 0; 3 | } 4 | 5 | @media (min-width: 768px) { 6 | .container { 7 | padding: 1.5rem 20% 0; 8 | } 9 | } 10 | 11 | @media (min-width: 992px) { 12 | .container { 13 | padding: 2.25rem 30% 0; 14 | } 15 | } -------------------------------------------------------------------------------- /src/components/container/container.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './container.css' 3 | 4 | function Container(props){ 5 | return ( 6 |
7 | {props.children} 8 |
9 | ) 10 | } 11 | 12 | export default Container -------------------------------------------------------------------------------- /src/components/container/container.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Container from './index' 4 | 5 | storiesOf('Components/Container', module) 6 | .add('default', () =>( 7 | 8 | Children Here 9 | 10 | )) -------------------------------------------------------------------------------- /src/components/container/index.js: -------------------------------------------------------------------------------- 1 | import Container from './container' 2 | 3 | export default Container -------------------------------------------------------------------------------- /src/components/form/button/button.css: -------------------------------------------------------------------------------- 1 | .button { 2 | color: white; 3 | font-size: 1.3rem; 4 | font-weight: bold; 5 | width: 100%; 6 | padding: 0.8rem; 7 | margin-bottom: 1rem; 8 | background: #9351b4; 9 | border: 1px solid #9351b4; 10 | border-radius: 5px; 11 | } 12 | 13 | .button--disabled { 14 | color: gray; 15 | background: lightgrey; 16 | border-color: lightgrey; 17 | } -------------------------------------------------------------------------------- /src/components/form/button/button.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './button.css' 3 | 4 | function Button(props){ 5 | let classes = 'button' 6 | 7 | if(props.disabled){ 8 | classes += ' button--disabled' 9 | } 10 | 11 | return( 12 | 15 | ) 16 | } 17 | 18 | export default Button -------------------------------------------------------------------------------- /src/components/form/button/button.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Button from './index' 4 | 5 | storiesOf('Components/Form/Button', module) 6 | .add('default', () =>( 7 | 8 | )) 9 | .add('with disabled', () =>( 10 | 11 | )) 12 | -------------------------------------------------------------------------------- /src/components/form/button/index.js: -------------------------------------------------------------------------------- 1 | import Button from './button' 2 | 3 | export default Button -------------------------------------------------------------------------------- /src/components/form/form.css: -------------------------------------------------------------------------------- 1 | .form { 2 | font-family: monospace; 3 | } 4 | .form__title { 5 | color: #9351b4; 6 | } 7 | .form__text{ 8 | font-size: 16px; 9 | } -------------------------------------------------------------------------------- /src/components/form/form.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Button from './button' 3 | import Input from './input' 4 | import Label from './label' 5 | import Link from './link' 6 | 7 | import './form.css' 8 | 9 | function Form(props) { 10 | return ( 11 |
12 |

{props.title}

13 |

{props.text}

14 | {props.children} 15 |
16 | ) 17 | } 18 | 19 | Form.Button = Button 20 | Form.Input = Input 21 | Form.Label = Label 22 | Form.Link = Link 23 | 24 | export default Form -------------------------------------------------------------------------------- /src/components/form/form.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Form from './index' 4 | 5 | 6 | storiesOf('Components/Form', module) 7 | .add('default', () =>( 8 |
9 | Nome 10 | 11 | 12 | )) 13 | -------------------------------------------------------------------------------- /src/components/form/index.js: -------------------------------------------------------------------------------- 1 | import Form from './form' 2 | 3 | export default Form -------------------------------------------------------------------------------- /src/components/form/input/index.js: -------------------------------------------------------------------------------- 1 | import Input from './input' 2 | 3 | export default Input -------------------------------------------------------------------------------- /src/components/form/input/input.css: -------------------------------------------------------------------------------- 1 | .input { 2 | font-size: 1rem; 3 | box-sizing: border-box; 4 | display: block; 5 | width: 100%; 6 | padding: 0.8rem; 7 | margin: 0 0 1rem; 8 | border: 1px solid black; 9 | border-radius: 5px; 10 | } 11 | .input:focus { 12 | outline: none; 13 | border-color: #9351b4; 14 | box-shadow: 0 0 10px #9351b4; 15 | } 16 | 17 | .input__erro { 18 | color: red; 19 | } 20 | -------------------------------------------------------------------------------- /src/components/form/input/input.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import './input.css' 3 | 4 | // function Input2(props){ 5 | // return ( 6 | // 12 | // ) 13 | // } 14 | 15 | class Input extends Component { 16 | constructor(props){ 17 | super(props) 18 | this.state={ 19 | message : null 20 | } 21 | this.value = '' 22 | } 23 | getValue = () => { 24 | return this.value 25 | } 26 | hasError = () => { 27 | if(this.state.message === null || this.state.message !== ''){ 28 | return true 29 | }else{ 30 | return false 31 | } 32 | } 33 | 34 | handleChange = (e) => { 35 | this.value = e.target.value 36 | const regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 37 | let message = '' 38 | if(this.props.required && this.value.trim() === ''){ 39 | message = 'Campo Obrigatório' 40 | }else if(this.value && this.props.minLength && this.value.length < (this.props.minLength)){ 41 | message = `Digite pelo menos ${this.props.minLength} caracteres` 42 | }else if(this.props.type==='email' && !regex.test(this.value)){ 43 | message= 'Digite um email válido' 44 | } 45 | this.setState({ message : message },this.props.onChange) 46 | 47 | } 48 | render() { 49 | return ( 50 | 51 | 60 |

{this.state.message}

61 |
62 | 63 | ) 64 | } 65 | 66 | } 67 | 68 | export default Input 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/components/form/input/input.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Input from './index' 4 | 5 | storiesOf('Components/Form/Input', module) 6 | .add('default', () =>( 7 | 8 | )) 9 | -------------------------------------------------------------------------------- /src/components/form/input/input2.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reprograma/t6-react-todo-list/9c2da5e20c61c795014740138905bb58d08b7f10/src/components/form/input/input2.js -------------------------------------------------------------------------------- /src/components/form/label/index.js: -------------------------------------------------------------------------------- 1 | import Label from './label' 2 | 3 | export default Label -------------------------------------------------------------------------------- /src/components/form/label/label.css: -------------------------------------------------------------------------------- 1 | .label { 2 | font-weight: bold; 3 | font-family: monospace; 4 | font-size: 18px; 5 | display: block; 6 | margin-bottom: 0.3rem; 7 | } -------------------------------------------------------------------------------- /src/components/form/label/label.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './label.css' 3 | 4 | function Label(props) { 5 | return ( 6 | 9 | ) 10 | } 11 | 12 | export default Label -------------------------------------------------------------------------------- /src/components/form/label/label.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import Label from './index' 4 | 5 | storiesOf('Components/Form/Label', module) 6 | .add('default', () =>( 7 | 8 | )) 9 | -------------------------------------------------------------------------------- /src/components/form/link/index.js: -------------------------------------------------------------------------------- 1 | import Link from './link' 2 | 3 | export default Link -------------------------------------------------------------------------------- /src/components/form/link/link.css: -------------------------------------------------------------------------------- 1 | .link { 2 | cursor: pointer; 3 | color: #9351b4; 4 | text-align: center; 5 | text-decoration: underline; 6 | display: block; 7 | } -------------------------------------------------------------------------------- /src/components/form/link/link.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link as LinkRouter } from 'react-router-dom' 3 | import './link.css' 4 | 5 | function Link(props){ 6 | return ( 7 | 8 | {props.children} 9 | 10 | ) 11 | } 12 | 13 | export default Link; 14 | -------------------------------------------------------------------------------- /src/components/form/link/link.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import StoryRouter from 'storybook-react-router' 4 | import Link from './index' 5 | 6 | 7 | storiesOf('Components/Form/Link', module) 8 | .addDecorator(StoryRouter()) 9 | .add('default', () =>( 10 | Link here 11 | )) 12 | 13 | -------------------------------------------------------------------------------- /src/components/navbar/index.js: -------------------------------------------------------------------------------- 1 | import Navbar from './navbar' 2 | 3 | export default Navbar -------------------------------------------------------------------------------- /src/components/navbar/logo-reprograma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reprograma/t6-react-todo-list/9c2da5e20c61c795014740138905bb58d08b7f10/src/components/navbar/logo-reprograma.png -------------------------------------------------------------------------------- /src/components/navbar/menu/index.js: -------------------------------------------------------------------------------- 1 | import Menu from './menu' 2 | 3 | export default Menu -------------------------------------------------------------------------------- /src/components/navbar/menu/menu.css: -------------------------------------------------------------------------------- 1 | .menu__button{ 2 | cursor: pointer; 3 | text-transform: uppercase; 4 | padding: 0.5rem; 5 | border: 1px solid #9351b4; 6 | border-radius: 5px; 7 | } 8 | 9 | .menu__button--open:after { 10 | content: ""; 11 | position: fixed; 12 | top: 0; 13 | right: 0; 14 | height: 100vh; 15 | width: 100vw; 16 | background: rgba(0, 0, 0, 0.5); 17 | } 18 | 19 | .menu__options { 20 | list-style: none; 21 | color: white; 22 | font-weight: bold; 23 | font-size: 18px; 24 | font-family: monospace; 25 | text-transform: uppercase; 26 | position: fixed; 27 | top: 0; 28 | left: 0; 29 | height: 100vh; 30 | width: 80vw; 31 | padding: 2rem 1rem 0; 32 | margin: 0; 33 | background: #9351b4; 34 | transform: translateX(-100%); 35 | transition: transform 1s ease-in-out; 36 | } 37 | 38 | .menu__options--open { 39 | transform: translateX(0); 40 | } 41 | 42 | .menu__options--active { 43 | border-bottom: 2px solid white; 44 | } 45 | 46 | .menu__options li + li { 47 | margin-top: 1rem; 48 | } 49 | 50 | .menu__options li a { 51 | cursor: pointer; 52 | color: white; 53 | text-transform: uppercase; 54 | text-decoration: none; 55 | } 56 | 57 | @media (min-width: 992px) { 58 | .menu__button { 59 | display: none; 60 | } 61 | 62 | .menu__options { 63 | display: flex; 64 | align-items: center; 65 | position: initial; 66 | height: initial; 67 | width: initial; 68 | padding: initial; 69 | background: initial; 70 | transform: initial; 71 | transition: initial; 72 | } 73 | 74 | .menu__options--open { 75 | transform: initial; 76 | } 77 | 78 | .menu__options--active { 79 | border-color: #9351b4; 80 | } 81 | 82 | .menu__options li + li { 83 | margin-top: 0; 84 | margin-left: 1rem; 85 | } 86 | 87 | .menu__options li a { 88 | color: #9351b4; 89 | padding: 0.3rem 0; 90 | } 91 | } -------------------------------------------------------------------------------- /src/components/navbar/menu/menu.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link,Redirect } from 'react-router-dom' 3 | import './menu.css' 4 | 5 | 6 | class Menu extends React.Component { 7 | constructor(props){ 8 | super(props) 9 | this.state = { open : false} 10 | } 11 | 12 | handleOpenOrClose = () => { 13 | this.setState({ open : !this.state.open}) 14 | } 15 | handleLoginOrLogout = (e) => { 16 | e.preventDefault() 17 | if(this.props.user){ 18 | localStorage.clear() 19 | } 20 | this.props.history.push('/login') 21 | } 22 | render(){ 23 | console.log('hello render') 24 | let classesOfButton = 'menu__button' 25 | let classesOfOptions = 'menu__options' 26 | 27 | if(this.state.open){ 28 | classesOfButton += ' menu__button--open' 29 | classesOfOptions += ' menu__options--open' 30 | } 31 | return ( 32 |
33 | 34 | Menu 35 | 36 | 53 |
54 | ) 55 | 56 | } 57 | } 58 | 59 | export default Menu -------------------------------------------------------------------------------- /src/components/navbar/menu/menu.stories.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reprograma/t6-react-todo-list/9c2da5e20c61c795014740138905bb58d08b7f10/src/components/navbar/menu/menu.stories.js -------------------------------------------------------------------------------- /src/components/navbar/navbar.css: -------------------------------------------------------------------------------- 1 | .navbar { 2 | display: flex; 3 | align-items: center; 4 | justify-content: space-between; 5 | flex: 0 60px; 6 | min-height: 60px; 7 | padding: 0 1rem; 8 | background: #ffffff; 9 | border-bottom: 1px solid #d4dadf; 10 | box-shadow: 0 1px 1px 0 #f0f1f4; 11 | } 12 | 13 | .navbar__logo { 14 | display: block; 15 | width: 200px; 16 | } 17 | 18 | 19 | @media (min-width: 992px) { 20 | .navbar { 21 | padding: 0 10%; 22 | } 23 | } -------------------------------------------------------------------------------- /src/components/navbar/navbar.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router-dom' 3 | import Menu from './menu' 4 | import logo from './logo-reprograma.png' 5 | import './navbar.css' 6 | 7 | const Navbar = (props) => ( 8 | 18 | ) 19 | 20 | export default Navbar -------------------------------------------------------------------------------- /src/components/navbar/navbar.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { storiesOf } from '@storybook/react' 3 | import StoryRouter from 'storybook-react-router' 4 | import Navbar from './index' 5 | 6 | 7 | storiesOf('Components/Navbar', module) 8 | .addDecorator(StoryRouter()) 9 | .add('default', () =>( 10 | 11 | )) 12 | 13 | -------------------------------------------------------------------------------- /src/components/postit/index.js: -------------------------------------------------------------------------------- 1 | import Postit from './postit' 2 | 3 | export default Postit -------------------------------------------------------------------------------- /src/components/postit/postit.css: -------------------------------------------------------------------------------- 1 | .postit { 2 | font-size: 1rem; 3 | display: flex; 4 | flex-direction: row; 5 | box-sizing: border-box; 6 | width: 100%; 7 | padding: 1rem; 8 | margin: 0 0 1.5rem; 9 | background: #ECDDF3; 10 | border-radius: 2px; 11 | box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14); 12 | } 13 | 14 | .postit__color { 15 | border-radius: 100%; 16 | background-color: transparent; 17 | border: none; 18 | width: 1.5rem; 19 | height: 1.5rem; 20 | /* float: right; */ 21 | display: block; 22 | margin-left: auto; 23 | } 24 | .postit__title { 25 | font-weight: bold; 26 | } 27 | 28 | .postit__button-remove { 29 | cursor: pointer; 30 | margin-left: auto; 31 | float: right; 32 | } 33 | 34 | .postit__button-completed { 35 | cursor: pointer; 36 | text-transform: uppercase; 37 | margin-left: auto; 38 | } 39 | 40 | .postit__title, 41 | .postit__text, 42 | .postit__button-remove, 43 | .postit__button-completed { 44 | pointer-events: auto; 45 | font-size: inherit; 46 | padding: 0.5rem; 47 | border: none; 48 | background: inherit; 49 | } 50 | 51 | .postit__title:focus, 52 | .postit__text:focus, 53 | .postit__button-completed:focus { 54 | outline: none; 55 | } 56 | 57 | @media (min-width: 992px) { 58 | .postit { 59 | display: inline-flex; 60 | width: 30%; 61 | } 62 | 63 | .postit:nth-child(3n + 2) { 64 | margin-left: 5%; 65 | margin-right: 5%; 66 | } 67 | } -------------------------------------------------------------------------------- /src/components/postit/postit.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Form from '../form' 3 | import { createPostit, deletePostit, updatePostitApi } from '../../apis/postit.api' 4 | 5 | import './postit.css' 6 | 7 | class Postit extends React.Component { 8 | constructor(props){ 9 | super(props) 10 | this.state = { 11 | id: this.props.id ? this.props.id : null, 12 | title: this.props.title ? this.props.title : '', 13 | text: this.props.text ? this.props.text : '', 14 | editing : false, 15 | color : this.props.color ? this.props.color : '#ECDDF3' 16 | } 17 | } 18 | handlePostitClick = () => { 19 | console.log('handlePostitClick') 20 | this.setState({ 21 | editing : true 22 | }) 23 | } 24 | handlePostitRemove = (e) =>{ 25 | console.log('handlePostitRemove') 26 | e.stopPropagation() 27 | const id = this.state.id 28 | deletePostit(id) 29 | .then((response) =>{ 30 | console.log(response) 31 | this.props.updatePostits() 32 | }) 33 | .catch((error)=>{ 34 | console.log(error) 35 | }) 36 | 37 | } 38 | handlePostitSubmit = (e) => { 39 | e.preventDefault() 40 | 41 | if(this.state.id){ 42 | const postit = { 43 | title : this.state.title, 44 | text : this.state.text, 45 | id : this.state.id, 46 | color: this.state.color 47 | } 48 | updatePostitApi(postit) 49 | .then((reponse)=>{ 50 | this.setState({ 51 | editing : false 52 | }) 53 | }) 54 | .catch((error)=>{ 55 | console.log(error) 56 | }) 57 | 58 | }else{ 59 | 60 | const postit = { 61 | title : this.state.title, 62 | text : this.state.text, 63 | color: this.state.color 64 | } 65 | 66 | createPostit(postit) 67 | .then((response) =>{ 68 | console.log(this) 69 | this.props.updatePostits() 70 | this.setState({ 71 | id : '', 72 | title : '', 73 | text : '', 74 | color: '#ECDDF3', 75 | editing: false 76 | }) 77 | }) 78 | .catch((error)=>{ 79 | console.log(error) 80 | }) 81 | } 82 | 83 | } 84 | setTitle = (e) => { 85 | const inputTitle = e.target.value 86 | console.log('evento ',e) 87 | this.setState({ 88 | title : inputTitle 89 | }) 90 | } 91 | setText = (event) => { 92 | const inputText = event.target.value 93 | this.setState({ 94 | text : inputText 95 | }) 96 | } 97 | setColor = (e) =>{ 98 | this.setState({ 99 | color : e.target.value 100 | }) 101 | } 102 | render() { 103 | return ( 104 |
105 | 106 |
107 | {this.state.editing && ( 108 | 115 | ) 116 | 117 | } 118 | 119 | 127 |