Skip to content

Commit

Permalink
Todo-app
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardomleitao committed Feb 17, 2017
1 parent 4043b88 commit 256bf45
Show file tree
Hide file tree
Showing 29 changed files with 506 additions and 0 deletions.
2 changes: 2 additions & 0 deletions todo-app/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
*.log
21 changes: 21 additions & 0 deletions todo-app/backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "src/loader.js",
"scripts": {
"dev": "nodemon",
"production": "pm2 start src/loader.js --name todo-app"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"mongoose": "^4.7.0",
"node-restful": "^0.2.5",
"nodemon": "^1.11.0",
"pm2": "^2.1.5"
}
}
10 changes: 10 additions & 0 deletions todo-app/backend/src/api/todo/todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const restful = require('node-restful')
const mongoose = restful.mongoose

const todoSchema = new mongoose.Schema({
description: { type: String, required: true },
done: { type: Boolean, required: true, default: false },
createdAt: { type: Date, default: Date.now }
})

module.exports = restful.model('Todo', todoSchema)
6 changes: 6 additions & 0 deletions todo-app/backend/src/api/todo/todoService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const Todo = require('./todo')

Todo.methods(['get', 'post', 'put', 'delete'])
Todo.updateOptions({new: true, runValidators: true})

module.exports = Todo
6 changes: 6 additions & 0 deletions todo-app/backend/src/config/cors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
next()
}
3 changes: 3 additions & 0 deletions todo-app/backend/src/config/database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
module.exports = mongoose.connect('mongodb://localhost/todo')
12 changes: 12 additions & 0 deletions todo-app/backend/src/config/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const express = require('express')

module.exports = function(server) {

// API Routes
const router = express.Router()
server.use('/api', router)

// TODO Routes
const todoService = require('../api/todo/todoService')
todoService.register(router, '/todos')
}
16 changes: 16 additions & 0 deletions todo-app/backend/src/config/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const port = 3003

const bodyParser = require('body-parser')
const express = require('express')
const server = express()
const allowCors = require('./cors')

server.use(bodyParser.urlencoded({ extended: true }))
server.use(bodyParser.json())
server.use(allowCors)

server.listen(port, function() {
console.log(`BACKEND is running on port ${port}.`)
})

module.exports = server
3 changes: 3 additions & 0 deletions todo-app/backend/src/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const server = require('./config/server')
require('./config/database')
require('./config/routes')(server)
2 changes: 2 additions & 0 deletions todo-app/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
*.log
38 changes: 38 additions & 0 deletions todo-app/frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server --progress --colors --inline --hot",
"production": "webpack --progress -p"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"axios": "^0.15.3",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-react-html-attrs": "^2.0.0",
"babel-plugin-transform-object-rest-spread": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0",
"bootstrap": "^3.3.7",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"font-awesome": "^4.7.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-redux": "^5.0.2",
"react-router": "^3.0.2",
"redux": "^3.6.0",
"redux-multi": "^0.1.12",
"redux-promise": "^0.5.3",
"redux-thunk": "^2.2.0",
"style-loader": "^0.13.1",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"
}
}
13 changes: 13 additions & 0 deletions todo-app/frontend/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>Todo App</title>
<link rel='stylesheet' href='app.css'>
</head>
<body>
<div id="app" class='container'></div>
<script src='app.js'></script>
</body>
</html>
15 changes: 15 additions & 0 deletions todo-app/frontend/src/about/about.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import PageHeader from '../template/pageHeader'

export default props => (
<div>
<PageHeader name='Sobre' small='Nós'></PageHeader>

<h2>Nossa História</h2>
<p>Lorem ipsum dolor sit amet...</p>
<h2>Missão e Visão</h2>
<p>Lorem ipsum dolor sit amet...</p>
<h2>Imprensa</h2>
<p>Lorem ipsum dolor sit amet...</p>
</div>
)
20 changes: 20 additions & 0 deletions todo-app/frontend/src/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { applyMiddleware, createStore } from 'redux'
import { Provider } from 'react-redux'

import promise from 'redux-promise'
import multi from 'redux-multi'
import thunk from 'redux-thunk'

import App from './main/app'
import reducers from './main/reducers'

const devTools = window.__REDUX_DEVTOOLS_EXTENSION__
&& window.__REDUX_DEVTOOLS_EXTENSION__()
const store = applyMiddleware(thunk, multi, promise)(createStore)(reducers, devTools)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('app'))
14 changes: 14 additions & 0 deletions todo-app/frontend/src/main/app.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'modules/bootstrap/dist/css/bootstrap.min.css'
import 'modules/font-awesome/css/font-awesome.min.css'
import '../template/custom.css'

import React from 'react'
import Menu from '../template/menu'
import Routes from './routes'

export default props => (
<div className='container'>
<Menu />
<Routes />
</div>
)
8 changes: 8 additions & 0 deletions todo-app/frontend/src/main/reducers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { combineReducers } from 'redux'
import todoReducer from '../todo/todoReducer'

const rootReducer = combineReducers({
todo: todoReducer
})

export default rootReducer
13 changes: 13 additions & 0 deletions todo-app/frontend/src/main/routes.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import { Router, Route, Redirect, hashHistory } from 'react-router'

import Todo from '../todo/todo'
import About from '../about/about'

export default props => (
<Router history={hashHistory}>
<Route path='/todos' component={Todo} />
<Route path='/about' component={About} />
<Redirect from='*' to='/todos' />
</Router>
)
16 changes: 16 additions & 0 deletions todo-app/frontend/src/template/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.btn {
margin-right: 5px;
}

.markedAsDone {
text-decoration: line-through;
color: #777;
}

.tableActions {
width: 105px;
}

.todoForm {
padding-bottom: 60px;
}
24 changes: 24 additions & 0 deletions todo-app/frontend/src/template/grid.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { Component } from 'react'

export default class Grid extends Component {
toCssClasses(numbers) {
const cols = numbers ? numbers.split(' ') : []
let classes = ''

if(cols[0]) classes += `col-xs-${cols[0]}`
if(cols[1]) classes += ` col-sm-${cols[1]}`
if(cols[2]) classes += ` col-md-${cols[2]}`
if(cols[3]) classes += ` col-lg-${cols[3]}`

return classes
}

render() {
const gridClasses = this.toCssClasses(this.props.cols || 12)
return (
<div className={gridClasses}>
{this.props.children}
</div>
)
}
}
11 changes: 11 additions & 0 deletions todo-app/frontend/src/template/iconButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import If from './if'

export default props => (
<If test={!props.hide}>
<button className={'btn btn-'+ props.style}
onClick={props.onClick}>
<i className={'fa fa-'+ props.icon}></i>
</button>
</If>
)
9 changes: 9 additions & 0 deletions todo-app/frontend/src/template/if.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

export default props => {
if(props.test) {
return props.children
} else {
return false
}
}
20 changes: 20 additions & 0 deletions todo-app/frontend/src/template/menu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react'

export default props => (
<nav className='navbar navbar-inverse bg-inverse'>
<div className='container'>
<div className='navbar-header'>
<a className='navbar-brand' href='#'>
<i className='fa fa-calendar-check-o'></i> TodoApp
</a>
</div>

<div id='navbar' className='navbar-collapse collapse'>
<ul className="nav navbar-nav">
<li><a href='#/todos'>Tarefas</a></li>
<li><a href='#/about'>Sobre</a></li>
</ul>
</div>
</div>
</nav>
)
7 changes: 7 additions & 0 deletions todo-app/frontend/src/template/pageHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react'

export default props => (
<header className='page-header'>
<h2>{props.name} <small>{props.small}</small></h2>
</header>
)
13 changes: 13 additions & 0 deletions todo-app/frontend/src/todo/todo.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'

import PageHeader from '../template/pageHeader'
import TodoForm from './todoForm'
import TodoList from './todoList'

export default props => (
<div>
<PageHeader name='Tarefas' small='Cadastro'></PageHeader>
<TodoForm />
<TodoList />
</div>
)
50 changes: 50 additions & 0 deletions todo-app/frontend/src/todo/todoActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import axios from 'axios'

const URL = 'http://localhost:3003/api/todos'

export const changeDescription = event => ({
type: 'DESCRIPTION_CHANGED',
payload: event.target.value
})

export const search = () => {
return (dispatch, getState) => {
const description = getState().todo.description
const search = description ? `&description__regex=/${description}/` : ''
const request = axios.get(`${URL}?sort=-createdAt${search}`)
.then(resp => dispatch({type: 'TODO_SEARCHED', payload: resp.data}))
}
}

export const add = (description) => {
return dispatch => {
axios.post(URL, { description })
.then(resp => dispatch(clear()))
.then(resp => dispatch(search()))
}
}

export const markAsDone = (todo) => {
return dispatch => {
axios.put(`${URL}/${todo._id}`, { ...todo, done: true })
.then(resp => dispatch(search()))
}
}

export const markAsPending = (todo) => {
return dispatch => {
axios.put(`${URL}/${todo._id}`, { ...todo, done: false })
.then(resp => dispatch(search()))
}
}

export const remove = (todo) => {
return dispatch => {
axios.delete(`${URL}/${todo._id}`)
.then(resp => dispatch(search()))
}
}

export const clear = () => {
return [{ type: 'TODO_CLEAR' }, search()]
}
Loading

0 comments on commit 256bf45

Please sign in to comment.