From 2cd153a4a125fe0bb242b5da8ce21118718f0561 Mon Sep 17 00:00:00 2001 From: Myer Nore Date: Fri, 1 Sep 2017 06:00:46 -0400 Subject: [PATCH 1/6] navbar includes name 'beetimer' and logo as well as indigo500 color redux - reset appearance #67 --- src/containers/Navbar/Navbar.js | 4 +++- src/containers/Navbar/Navbar.scss | 6 ++++-- src/static/beetimer_yellow_128.png | Bin 0 -> 1106 bytes src/theme.js | 4 ++-- yarn.lock | 6 +++--- 5 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 src/static/beetimer_yellow_128.png diff --git a/src/containers/Navbar/Navbar.js b/src/containers/Navbar/Navbar.js index c90379d..8608265 100644 --- a/src/containers/Navbar/Navbar.js +++ b/src/containers/Navbar/Navbar.js @@ -19,6 +19,7 @@ import FlatButton from 'material-ui/FlatButton' import DownArrow from 'material-ui/svg-icons/hardware/keyboard-arrow-down' import Avatar from 'material-ui/Avatar' import defaultUserImage from 'static/User.png' +import beetimerLogo from 'static/beetimer_yellow_128.png' const buttonStyle = { color: 'white', @@ -119,13 +120,14 @@ export default class Navbar extends Component { to={accountExists ? `${LIST_PATH}` : '/'} className={classes.brand} > - material example + Beetimer } showMenuIconButton={false} iconElementRight={rightMenu} iconStyleRight={accountExists ? avatarStyles.wrapper : {}} className={classes.appBar} + // style={{ backgroundColor: Theme.palette.accent1Color }} /> ) } diff --git a/src/containers/Navbar/Navbar.scss b/src/containers/Navbar/Navbar.scss index 7863b7f..7f6bb23 100644 --- a/src/containers/Navbar/Navbar.scss +++ b/src/containers/Navbar/Navbar.scss @@ -6,14 +6,16 @@ font-weight: 200; .icon { height: 50px; - margin-top: 7px; + margin-right: 7px; @include mobile { width: 3rem; height: 3rem; - margin-top: 1.1rem; } } } +.appBar { + //border: dashed firebrick 3px; +} .appBar > div { @extend .flex-row; align-items: center; diff --git a/src/static/beetimer_yellow_128.png b/src/static/beetimer_yellow_128.png new file mode 100644 index 0000000000000000000000000000000000000000..35b2cb34c00241a96079185b5c624652b4ee337a GIT binary patch literal 1106 zcmV-Y1g-mtP)>@WyLV=G(eYG(ai%`77Q8fo-2ddegiE^w~YzqSc*jO_%IZ9@nlgb+dq zA=F4Cy8*}ZafCYX=Qp(vCu5+u0000G03ZNB0Du4h0RRF31ONyjgb+dqp{g3y4ZK?~ zko|psD*(KTLn=W*MNo4X20_x*|-vdLEz&-IAiB3 z2nNBAh2R@IS3ocbd>jZ@Y_*195d0Vj?$~Mx!65K8*A;01Aoz_l0Ktz9ekcG0KR)v@yN^$!0LV~| zHZujk+x+bT`y}|iA(&Mihb_SXsJ!i}0Kv*EFc~eqZJSD?zxpAJJ2tM$0`v!Hu90!{ zS2!1-k|k$0$FUv|o&q|b&GWh^Yah?7j#GjlvkfDXOzX3BSx0_kdH9}n4pmtQzV0LI zIwmXwTya?C!=WDjTL!@D6xRK4=t>A=9|RrG$MO2{4u;j}vb_IQ+SNveO6izoVaJ)K z4|k7?rC$VE7;gpE@q8Tb|7!&dDvQQFI&iB4zcPE>xpxZ?{slEf2C#CV#6uJVTi$~h zF%5)F0p2e{u3Yci(e?V>tJjKxde0F2Ob=P^WQEp?!0dsy&I)e#sIYop8F;12WJO=? zjQHLeVRjDw`1u`C*98Cvhn#J`=<#Gy6@uAudp<60&7+gAK#&=p60`Wp&D8mCC>|0UR7OnWXMs-}O{ zG*c!6+!-+|nk%jTV1s9~s}fO52k&oi(ic@Kxz^ zI8;a9w+>dX2T*N?GdxCgH3+H%UvdigpBjKO4)X|#YNd}X0G=s&6#$j`28FGfz0TWP_6e-m zBOrX+)V-E4dh05&Z|({~sn5m%LB8Ni0niD8@)bdVpdWZ?04hSDT3IY#?wlP2^^)>5 z_3qg~$a0n--GPU!heH9NI0)@O9^Da!3P;9Do_VYOkp}>9fTHt Date: Sat, 2 Sep 2017 06:22:36 -0400 Subject: [PATCH 2/6] default route is now emptied and todos are moved to their own route * will remove todos and projects in time redux - reset appearance #67 --- src/constants.js | 2 + src/routes/Home/containers/HomeContainer.js | 131 +++------------- src/routes/Home/containers/HomeContainer.scss | 9 +- .../components/NewTodoPanel/NewTodoPanel.js | 0 .../components/NewTodoPanel/NewTodoPanel.scss | 0 .../components/NewTodoPanel/index.js | 0 .../components/TodoItem/TodoItem.js | 0 .../components/TodoItem/TodoItem.scss | 0 .../components/TodoItem/index.js | 0 src/routes/Todos/containers/TodosContainer.js | 140 ++++++++++++++++++ .../Todos/containers/TodosContainer.scss | 16 ++ src/routes/Todos/index.js | 8 + src/routes/index.js | 2 + 13 files changed, 188 insertions(+), 120 deletions(-) rename src/routes/{Home => Todos}/components/NewTodoPanel/NewTodoPanel.js (100%) rename src/routes/{Home => Todos}/components/NewTodoPanel/NewTodoPanel.scss (100%) rename src/routes/{Home => Todos}/components/NewTodoPanel/index.js (100%) rename src/routes/{Home => Todos}/components/TodoItem/TodoItem.js (100%) rename src/routes/{Home => Todos}/components/TodoItem/TodoItem.scss (100%) rename src/routes/{Home => Todos}/components/TodoItem/index.js (100%) create mode 100755 src/routes/Todos/containers/TodosContainer.js create mode 100755 src/routes/Todos/containers/TodosContainer.scss create mode 100755 src/routes/Todos/index.js diff --git a/src/constants.js b/src/constants.js index 74a2d3b..1edea6e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,4 +1,5 @@ export const LIST_PATH = '/projects' +export const TODOS_PATH = '/todos' export const DETAIL_PATH = ':projectname' export const ACCOUNT_PATH = '/account' export const LOGIN_PATH = '/login' @@ -21,6 +22,7 @@ export const formNames = { export const paths = { list: LIST_PATH, + todos: TODOS_PATH, account: ACCOUNT_PATH, detail: DETAIL_PATH, login: LOGIN_PATH, diff --git a/src/routes/Home/containers/HomeContainer.js b/src/routes/Home/containers/HomeContainer.js index 7bfdbe6..29b5399 100755 --- a/src/routes/Home/containers/HomeContainer.js +++ b/src/routes/Home/containers/HomeContainer.js @@ -1,55 +1,32 @@ -import React, { Component, PropTypes } from 'react' -import { connect } from 'react-redux' -import { map } from 'lodash' +import React, {Component, PropTypes} from 'react' +import {connect} from 'react-redux' import Theme from 'theme' -import { - firebaseConnect, - isLoaded, - pathToJS, - dataToJS, // needed for full list and once - // orderedToJS, // needed for ordered list - // populatedDataToJS // needed for populated list -} from 'react-redux-firebase' -import CircularProgress from 'material-ui/CircularProgress' +import {dataToJS, firebaseConnect, isLoaded, pathToJS,} from 'react-redux-firebase' import Snackbar from 'material-ui/Snackbar' -import { List } from 'material-ui/List' -import Paper from 'material-ui/Paper' -import Subheader from 'material-ui/Subheader' -import TodoItem from '../components/TodoItem' -import NewTodoPanel from '../components/NewTodoPanel' import classes from './HomeContainer.scss' -const populates = [{ child: 'owner', root: 'users', keyProp: 'uid' }] +const populates = [{child: 'owner', root: 'users', keyProp: 'uid'}] @firebaseConnect([ // 'todos' // sync full list of todos // { path: 'todos', type: 'once' } // for loading once instead of binding - { path: 'todos', queryParams: ['orderByKey', 'limitToLast=5'] } // 10 most recent + // { path: 'todos', queryParams: ['orderByKey', 'limitToLast=5'] } // 10 most recent // { path: 'todos', populates } // populate // { path: 'todos', storeAs: 'myTodos' } // store elsewhere in redux ]) -@connect(({ firebase }) => ({ - auth: pathToJS(firebase, 'auth'), +@connect(({firebase}) => ({ + auth: pathToJS(firebase, 'auth'), account: pathToJS(firebase, 'profile'), - todos: dataToJS(firebase, 'todos'), - // todos: orderedToJS(firebase, 'todos') // if looking for array - // todos: dataToJS(firebase, 'myTodos'), // if using storeAs - // todos: populatedDataToJS(firebase, 'todos', populates), // if populating - // todos: orderedToJS(firebase, '/todos') // if using ordering such as orderByChild })) export default class Home extends Component { static propTypes = { - todos: PropTypes.oneOfType([ - PropTypes.object, // object if using dataToJS - PropTypes.array // array if using orderedToJS - ]), firebase: PropTypes.shape({ - set: PropTypes.func.isRequired, - remove: PropTypes.func.isRequired, - push: PropTypes.func.isRequired, + set: PropTypes.func.isRequired, + remove: PropTypes.func.isRequired, + push: PropTypes.func.isRequired, database: PropTypes.oneOfType([PropTypes.object, PropTypes.func]) }), - auth: PropTypes.shape({ + auth: PropTypes.shape({ uid: PropTypes.string }) } @@ -58,93 +35,23 @@ export default class Home extends Component { error: null } - toggleDone = (todo, id) => { - const { firebase, auth } = this.props - if (!auth || !auth.uid) { - return this.setState({ error: 'You must be Logged into Toggle Done' }) - } - return firebase.set(`/todos/${id}/done`, !todo.done) - } - - deleteTodo = id => { - const { todos, auth, firebase } = this.props - if (!auth || !auth.uid) { - return this.setState({ error: 'You must be Logged into Delete' }) - } - // return this.setState({ error: 'Delete example requires using populate' }) - // only works if populated - if (todos[id].owner !== auth.uid) { - return this.setState({ error: 'You must own todo to delete' }) - } - return firebase.remove(`/todos/${id}`).catch(err => { - console.error('Error removing todo: ', err) // eslint-disable-line no-console - this.setState({ error: 'Error Removing todo' }) - return Promise.reject(err) - }) - } - - handleAdd = newTodo => { - // Attach user if logged in - if (this.props.auth) { - newTodo.owner = this.props.auth.uid - } else { - newTodo.owner = 'Anonymous' - } - // attach a timestamp - newTodo.createdAt = this.props.firebase.database.ServerValue.TIMESTAMP - // using this.props.firebase.pushWithMeta here instead would automatically attach createdBy and createdAt - return this.props.firebase.push('/todos', newTodo) - } - render() { - const { todos } = this.props - const { error } = this.state + const {todos} = this.props + const {error} = this.state return (
{error ? this.setState({ error: null })} - /> + open={!!error} + message={error} + autoHideDuration={4000} + onRequestClose={() => this.setState({error: null})} + /> : null} -
- data loaded from - - - redux-firebasev3.firebaseio.com - - - - Note: - old data is removed - -
-
- - {!isLoaded(todos) - ? - : - Todos - - {todos && - map(todos, (todo, id) => - - )} - - } -
) } diff --git a/src/routes/Home/containers/HomeContainer.scss b/src/routes/Home/containers/HomeContainer.scss index eb74576..bb47715 100755 --- a/src/routes/Home/containers/HomeContainer.scss +++ b/src/routes/Home/containers/HomeContainer.scss @@ -3,14 +3,7 @@ @extend .flex-column-center; padding-top: 4rem; } -.todos { - @extend .flex-column-center; - margin-top: 4rem; -} .paper { padding: 1rem; margin-bottom: 4rem; -} -.info { - @extend .flex-column-center; -} +} \ No newline at end of file diff --git a/src/routes/Home/components/NewTodoPanel/NewTodoPanel.js b/src/routes/Todos/components/NewTodoPanel/NewTodoPanel.js similarity index 100% rename from src/routes/Home/components/NewTodoPanel/NewTodoPanel.js rename to src/routes/Todos/components/NewTodoPanel/NewTodoPanel.js diff --git a/src/routes/Home/components/NewTodoPanel/NewTodoPanel.scss b/src/routes/Todos/components/NewTodoPanel/NewTodoPanel.scss similarity index 100% rename from src/routes/Home/components/NewTodoPanel/NewTodoPanel.scss rename to src/routes/Todos/components/NewTodoPanel/NewTodoPanel.scss diff --git a/src/routes/Home/components/NewTodoPanel/index.js b/src/routes/Todos/components/NewTodoPanel/index.js similarity index 100% rename from src/routes/Home/components/NewTodoPanel/index.js rename to src/routes/Todos/components/NewTodoPanel/index.js diff --git a/src/routes/Home/components/TodoItem/TodoItem.js b/src/routes/Todos/components/TodoItem/TodoItem.js similarity index 100% rename from src/routes/Home/components/TodoItem/TodoItem.js rename to src/routes/Todos/components/TodoItem/TodoItem.js diff --git a/src/routes/Home/components/TodoItem/TodoItem.scss b/src/routes/Todos/components/TodoItem/TodoItem.scss similarity index 100% rename from src/routes/Home/components/TodoItem/TodoItem.scss rename to src/routes/Todos/components/TodoItem/TodoItem.scss diff --git a/src/routes/Home/components/TodoItem/index.js b/src/routes/Todos/components/TodoItem/index.js similarity index 100% rename from src/routes/Home/components/TodoItem/index.js rename to src/routes/Todos/components/TodoItem/index.js diff --git a/src/routes/Todos/containers/TodosContainer.js b/src/routes/Todos/containers/TodosContainer.js new file mode 100755 index 0000000..5d0c5e9 --- /dev/null +++ b/src/routes/Todos/containers/TodosContainer.js @@ -0,0 +1,140 @@ +import React, { Component, PropTypes } from 'react' +import { connect } from 'react-redux' +import { map } from 'lodash' +import Theme from 'theme' +import { + firebaseConnect, + isLoaded, + pathToJS, + dataToJS, // needed for full list and once + // orderedToJS, // needed for ordered list + // populatedDataToJS // needed for populated list +} from 'react-redux-firebase' +import CircularProgress from 'material-ui/CircularProgress' +import Snackbar from 'material-ui/Snackbar' +import { List } from 'material-ui/List' +import Paper from 'material-ui/Paper' +import Subheader from 'material-ui/Subheader' +import TodoItem from '../components/TodoItem' +import NewTodoPanel from '../components/NewTodoPanel' +import classes from './TodosContainer.scss' + +const populates = [{ child: 'owner', root: 'users', keyProp: 'uid' }] + +@firebaseConnect([ + // 'todos' // sync full list of todos + // { path: 'todos', type: 'once' } // for loading once instead of binding + { path: 'todos', queryParams: ['orderByKey', 'limitToLast=5'] } // 10 most recent + // { path: 'todos', populates } // populate + // { path: 'todos', storeAs: 'myTodos' } // store elsewhere in redux +]) +@connect(({ firebase }) => ({ + auth: pathToJS(firebase, 'auth'), + account: pathToJS(firebase, 'profile'), + todos: dataToJS(firebase, 'todos'), + // todos: orderedToJS(firebase, 'todos') // if looking for array + // todos: dataToJS(firebase, 'myTodos'), // if using storeAs + // todos: populatedDataToJS(firebase, 'todos', populates), // if populating + // todos: orderedToJS(firebase, '/todos') // if using ordering such as orderByChild +})) +export default class Home extends Component { + static propTypes = { + todos: PropTypes.oneOfType([ + PropTypes.object, // object if using dataToJS + PropTypes.array // array if using orderedToJS + ]), + firebase: PropTypes.shape({ + set: PropTypes.func.isRequired, + remove: PropTypes.func.isRequired, + push: PropTypes.func.isRequired, + database: PropTypes.oneOfType([PropTypes.object, PropTypes.func]) + }), + auth: PropTypes.shape({ + uid: PropTypes.string + }) + } + + state = { + error: null + } + + toggleDone = (todo, id) => { + const { firebase, auth } = this.props + if (!auth || !auth.uid) { + return this.setState({ error: 'You must be Logged into Toggle Done' }) + } + return firebase.set(`/todos/${id}/done`, !todo.done) + } + + deleteTodo = id => { + const { todos, auth, firebase } = this.props + if (!auth || !auth.uid) { + return this.setState({ error: 'You must be Logged into Delete' }) + } + // return this.setState({ error: 'Delete example requires using populate' }) + // only works if populated + if (todos[id].owner !== auth.uid) { + return this.setState({ error: 'You must own todo to delete' }) + } + return firebase.remove(`/todos/${id}`).catch(err => { + console.error('Error removing todo: ', err) // eslint-disable-line no-console + this.setState({ error: 'Error Removing todo' }) + return Promise.reject(err) + }) + } + + handleAdd = newTodo => { + // Attach user if logged in + if (this.props.auth) { + newTodo.owner = this.props.auth.uid + } else { + newTodo.owner = 'Anonymous' + } + // attach a timestamp + newTodo.createdAt = this.props.firebase.database.ServerValue.TIMESTAMP + // using this.props.firebase.pushWithMeta here instead would automatically attach createdBy and createdAt + return this.props.firebase.push('/todos', newTodo) + } + + render() { + const { todos } = this.props + const { error } = this.state + + return ( +
+ {error + ? this.setState({ error: null })} + /> + : null} +
+
+ + {!isLoaded(todos) + ? + : + Todos + + {todos && + map(todos, (todo, id) => + + )} + + } +
+
+ ) + } +} diff --git a/src/routes/Todos/containers/TodosContainer.scss b/src/routes/Todos/containers/TodosContainer.scss new file mode 100755 index 0000000..eb74576 --- /dev/null +++ b/src/routes/Todos/containers/TodosContainer.scss @@ -0,0 +1,16 @@ +@import 'base'; +.container { + @extend .flex-column-center; + padding-top: 4rem; +} +.todos { + @extend .flex-column-center; + margin-top: 4rem; +} +.paper { + padding: 1rem; + margin-bottom: 4rem; +} +.info { + @extend .flex-column-center; +} diff --git a/src/routes/Todos/index.js b/src/routes/Todos/index.js new file mode 100755 index 0000000..30f0c25 --- /dev/null +++ b/src/routes/Todos/index.js @@ -0,0 +1,8 @@ +import TodosContainer from './containers/TodosContainer' +import { TODOS_PATH as path } from 'constants' + +// Sync route definition +export default { + path, + component: TodosContainer +} diff --git a/src/routes/index.js b/src/routes/index.js index 2292497..47330c0 100755 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,6 +1,7 @@ // We only need to import the modules necessary for initial render import CoreLayout from '../layouts/CoreLayout/CoreLayout' import Home from './Home' +import Todos from './Todos' import LoginRoute from './Login' import SignupRoute from './Signup' import ProjectsRoute from './Projects' @@ -18,6 +19,7 @@ export const createRoutes = store => ({ AccountRoute, LoginRoute, SignupRoute, + Todos, ProjectsRoute(store), // async route definitions recieve store RecoverRoute(store) // async route definitions recieve store ] From 51ad30277e09ca27b897ee05908af736cdb4c477 Mon Sep 17 00:00:00 2001 From: Myer Nore Date: Sat, 2 Sep 2017 07:24:36 -0400 Subject: [PATCH 3/6] use ubutnu trusty for ci, and lock down node-sass redux - reset appearance #67 --- .travis.yml | 3 ++- package.json | 2 +- yarn.lock | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9c8531..224ba6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,5 @@ cache: - node_modules script: - yarn build - - yarn test \ No newline at end of file + - yarn test +dist: trusty \ No newline at end of file diff --git a/package.json b/package.json index 5ecc671..90f82f9 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "jest": "^20.0.4", "json-loader": "^0.5.4", "mocha": "^3.0.1", - "node-sass": "^3.7.0", + "node-sass": "3.13.1", "nodemon": "^1.10.2", "postcss-loader": "^0.13.0", "prettier": "^1.5.2", diff --git a/yarn.lock b/yarn.lock index 272339c..866c980 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4131,7 +4131,7 @@ node-pre-gyp@^0.6.36: tar "^2.2.1" tar-pack "^3.4.0" -node-sass@^3.7.0: +node-sass@3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-3.13.1.tgz#7240fbbff2396304b4223527ed3020589c004fc2" dependencies: From 3d12654517821c8a636d7476a5d90edaf0087c5c Mon Sep 17 00:00:00 2001 From: Myer Nore Date: Sat, 2 Sep 2017 07:31:52 -0400 Subject: [PATCH 4/6] add sudo false because of travis docs * see https://docs.travis-ci.com/user/reference/overview/ redux - reset appearance #67 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 224ba6d..286c9c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,4 +11,5 @@ cache: script: - yarn build - yarn test -dist: trusty \ No newline at end of file +dist: trusty +sudo: false \ No newline at end of file From 6c86f211e27b8affc388ff7803dcbfbc95cff511 Mon Sep 17 00:00:00 2001 From: Myer Nore Date: Sat, 2 Sep 2017 07:37:37 -0400 Subject: [PATCH 5/6] add group: edge to get the latest trusty image * see https://blog.travis-ci.com/2017-06-19-trusty-updates-2017-Q2 redux - reset appearance #67 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 286c9c7..84e2209 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,5 @@ script: - yarn build - yarn test dist: trusty -sudo: false \ No newline at end of file +sudo: false +group: edge \ No newline at end of file From 2b247c9918abd6ba83d4ac8c3efde0a384d2a411 Mon Sep 17 00:00:00 2001 From: Myer Nore Date: Sat, 2 Sep 2017 07:46:58 -0400 Subject: [PATCH 6/6] try sudo required * see https://github.com/travis-ci/travis-ci/issues/7566#issuecomment-324138144 redux - reset appearance #67 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 84e2209..7afcc03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,5 +12,5 @@ script: - yarn build - yarn test dist: trusty -sudo: false +sudo: required group: edge \ No newline at end of file