From b02935b9e1cec1b26417c8c50de540f18a881b14 Mon Sep 17 00:00:00 2001 From: Jag Date: Tue, 25 Jun 2019 16:16:15 -0700 Subject: [PATCH 1/7] starter code --- public/index.html | 52 ++++++++++++--- src/app.js | 18 ++--- src/components/counter/counter.js | 7 ++ src/components/if/index.js | 28 ++++++++ src/components/todo/todo.js | 107 ++++++++++++++++++++++++++++++ src/components/todo/todo.scss | 49 ++++++++++++++ src/index.js | 9 +-- 7 files changed, 244 insertions(+), 26 deletions(-) mode change 100644 => 100755 public/index.html mode change 100644 => 100755 src/app.js create mode 100755 src/components/counter/counter.js create mode 100755 src/components/if/index.js create mode 100755 src/components/todo/todo.js create mode 100755 src/components/todo/todo.scss mode change 100644 => 100755 src/index.js diff --git a/public/index.html b/public/index.html old mode 100644 new mode 100755 index 6d0bdf6..42ae2d2 --- a/public/index.html +++ b/public/index.html @@ -1,13 +1,43 @@ - - - - - React App - - - -
- - + + + + + + + + + + React App + + + + +
+ + + + \ No newline at end of file diff --git a/src/app.js b/src/app.js old mode 100644 new mode 100755 index 26c584f..237a4bf --- a/src/app.js +++ b/src/app.js @@ -1,11 +1,13 @@ import React from 'react'; -export default function App() { - return ( -
-
-

Hello, World!

-
-
- ); +import ToDo from './components/todo/todo.js'; + +export default class App extends React.Component { + render() { + return ( + <> + + + ); + } } diff --git a/src/components/counter/counter.js b/src/components/counter/counter.js new file mode 100755 index 0000000..c4b648f --- /dev/null +++ b/src/components/counter/counter.js @@ -0,0 +1,7 @@ +import React from 'react'; + +const Count = props => { + return

There are {props.count} items in the list

; +}; + +export default Count; diff --git a/src/components/if/index.js b/src/components/if/index.js new file mode 100755 index 0000000..79da480 --- /dev/null +++ b/src/components/if/index.js @@ -0,0 +1,28 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const render = (condition = false, children = null) => { + return !!condition ? children : null; +}; + +export const If = props => + React.Children.map(props.children, child => + React.cloneElement(child, { condition: props.condition }), + ); + +export const Then = props => render(props.condition, props.children); +export const Else = props => render(!props.condition, props.children); + +/* + +

When Works

+
+*/ +export const When = props => render(props.condition, props.children); + +/* + + Pay more $$ and we will make you an admin + +*/ +export const Unless = props => render(!props.condition, props.children); diff --git a/src/components/todo/todo.js b/src/components/todo/todo.js new file mode 100755 index 0000000..9738430 --- /dev/null +++ b/src/components/todo/todo.js @@ -0,0 +1,107 @@ +import React from "react"; +import uuid from "uuid/v4"; +import Counter from "../counter/counter.js"; +import { When } from "../if"; + +import "./todo.scss"; + +class ToDo extends React.Component { + constructor(props) { + super(props); + this.state = { todoList: [], item: {}, editing: false }; + } + + handleInputChange = e => { + let item = { + text: e.target.value, + complete: !!e.target.complete, + id: e.target.id || uuid() + }; + this.setState({ item }); + }; + + addItem = e => { + e.preventDefault(); + e.target.reset(); + this.setState({ todoList: [...this.state.todoList, this.state.item] }); + }; + + updateItem = e => { + e.preventDefault(); + this.saveItem(this.state.item); + }; + + toggleComplete = id => { + let item = this.state.todoList.filter(i => i.id === id)[0] || {}; + if (item.id) { + item.complete = !item.complete; + this.saveItem(item); + } + }; + + saveItem = updatedItem => { + this.setState({ + todoList: this.state.todoList.map(item => + item.id === updatedItem.id ? updatedItem : item + ), + editing: false + }); + }; + + toggleEdit = id => { + let editing = this.state.editing === id ? false : id; + this.setState({ editing }); + }; + + render() { + return ( + <> +
+
+ +
+ +
+
+ +
+
+ +
+
    + {this.state.todoList && + this.state.todoList.map(item => ( +
  • + this.toggleComplete(item.id)}> + {item.text} + + + +
    + +
    +
    +
  • + ))} +
+
+
+ + ); + } +} + +export default ToDo; diff --git a/src/components/todo/todo.scss b/src/components/todo/todo.scss new file mode 100755 index 0000000..db10b0b --- /dev/null +++ b/src/components/todo/todo.scss @@ -0,0 +1,49 @@ +.todo { + + ul { + list-style-type:none; + margin:0; + padding:0; + + li { + + align-items: center; + display:flex; + flex-direction:row; + margin: .75em .5em; + + &.complete-true { + span { + background: pink; + text-decoration:line-through; + &:hover { + background: seagreen; + } + } + } + + span { + background: #eee; + border-radius: 4px; + border: 1px solid #555; + cursor:pointer; + padding: .5em; + + &:hover { + background: pink; + } + } + + button { + background: transparent; + border:none; + color:blue; + cursor:pointer; + padding:0; + margin: 0 .75em; + } + + } + } + +} \ No newline at end of file diff --git a/src/index.js b/src/index.js old mode 100644 new mode 100755 index 40f3fad..d8a33b2 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import App from './app'; -import * as serviceWorker from './serviceWorker'; + +import App from './app.js'; class Main extends React.Component { render() { @@ -11,8 +11,3 @@ class Main extends React.Component { const rootElement = document.getElementById('root'); ReactDOM.render(
, rootElement); - -// If you want your app to work offline and load faster, you can change -// unregister() to register() below. Note this comes with some pitfalls. -// Learn more about service workers: https://bit.ly/CRA-PWA -serviceWorker.unregister(); From 07e2c89854babbd262d0d76267340ef5f0c45225 Mon Sep 17 00:00:00 2001 From: Jag Date: Tue, 25 Jun 2019 16:55:32 -0700 Subject: [PATCH 2/7] added counter context --- package.json | 3 +- src/app.js | 2 +- src/components/context/counter-context.js | 40 ++++++++++++ .../counter/counter-using-context.js | 12 ++++ src/components/counter/counter.js | 7 +- src/components/if/index.js | 10 ++- src/components/todo/todo.js | 64 +++++++++---------- src/index.js | 2 +- 8 files changed, 92 insertions(+), 48 deletions(-) create mode 100644 src/components/context/counter-context.js create mode 100644 src/components/counter/counter-using-context.js diff --git a/package.json b/package.json index b11a21f..ccda618 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "react": "^16.8.6", "react-dom": "^16.8.6", "react-scripts": "3.0.1", - "react-test-renderer": "^16.8.6" + "react-test-renderer": "^16.8.6", + "uuid": "^3.3.2" }, "devDependencies": { "eslint-config-airbnb-base": "^13.1.0", diff --git a/src/app.js b/src/app.js index 237a4bf..eebbff8 100755 --- a/src/app.js +++ b/src/app.js @@ -1,6 +1,6 @@ import React from 'react'; -import ToDo from './components/todo/todo.js'; +import ToDo from './components/todo/todo'; export default class App extends React.Component { render() { diff --git a/src/components/context/counter-context.js b/src/components/context/counter-context.js new file mode 100644 index 0000000..5b6e64d --- /dev/null +++ b/src/components/context/counter-context.js @@ -0,0 +1,40 @@ +/* eslint-disable react/prop-types */ + +import React from 'react'; + +export const CounterContext = React.createContext(); + +export default class ContextProvider extends React.Component { + constructor(props) { + super(props); + + this.state = { + count: 0, + increment: this.increment, + decrement: this.decrement, + }; + } + + updateCounter = (count) => { + this.setState({ count }); + }; + + increment = (event) => { + event.preventDefault(); + this.updateCounter(this.state.count + 1); + }; + + decrement = (event) => { + event.preventDefault(); + this.updateCounter(this.state.count - 1); + }; + + render() { + return ( + + {/* Everything inside Context.Provider will have access it its context */} + {this.props.children} + + ); + } +} diff --git a/src/components/counter/counter-using-context.js b/src/components/counter/counter-using-context.js new file mode 100644 index 0000000..6606898 --- /dev/null +++ b/src/components/counter/counter-using-context.js @@ -0,0 +1,12 @@ +/* eslint-disable react/prop-types */ +import React from 'react'; + +import { CounterContext } from '../context/counter-context'; + +export default class Count extends React.Component { + static contextType = CounterContext; + + render() { + return

Context: There are {this.context.count} items in the list

; + } +} diff --git a/src/components/counter/counter.js b/src/components/counter/counter.js index c4b648f..dcf2b4b 100755 --- a/src/components/counter/counter.js +++ b/src/components/counter/counter.js @@ -1,7 +1,6 @@ +/* eslint-disable react/prop-types */ import React from 'react'; -const Count = props => { +export default function Count(props) { return

There are {props.count} items in the list

; -}; - -export default Count; +} diff --git a/src/components/if/index.js b/src/components/if/index.js index 79da480..e999084 100755 --- a/src/components/if/index.js +++ b/src/components/if/index.js @@ -1,14 +1,12 @@ import React from 'react'; -import PropTypes from 'prop-types'; const render = (condition = false, children = null) => { - return !!condition ? children : null; + return condition ? children : null; }; -export const If = props => - React.Children.map(props.children, child => - React.cloneElement(child, { condition: props.condition }), - ); +export const If = props => React.Children.map(props.children, (child) => { + return React.cloneElement(child, { condition: props.condition }); +}); export const Then = props => render(props.condition, props.children); export const Else = props => render(!props.condition, props.children); diff --git a/src/components/todo/todo.js b/src/components/todo/todo.js index 9738430..2036bcc 100755 --- a/src/components/todo/todo.js +++ b/src/components/todo/todo.js @@ -1,9 +1,12 @@ -import React from "react"; -import uuid from "uuid/v4"; -import Counter from "../counter/counter.js"; -import { When } from "../if"; +import React from 'react'; +import uuid from 'uuid/v4'; +import Counter from '../counter/counter'; +import { When } from '../if'; -import "./todo.scss"; +import CounterWithContext from '../counter/counter-using-context'; +import CounterContextProvider from '../context/counter-context'; +import { CounterContext } from '../context/counter-context'; +import './todo.scss'; class ToDo extends React.Component { constructor(props) { @@ -11,45 +14,43 @@ class ToDo extends React.Component { this.state = { todoList: [], item: {}, editing: false }; } - handleInputChange = e => { - let item = { + handleInputChange = (e) => { + const item = { text: e.target.value, complete: !!e.target.complete, - id: e.target.id || uuid() + id: e.target.id || uuid(), }; this.setState({ item }); }; - addItem = e => { + addItem = (e) => { e.preventDefault(); e.target.reset(); this.setState({ todoList: [...this.state.todoList, this.state.item] }); }; - updateItem = e => { + updateItem = (e) => { e.preventDefault(); this.saveItem(this.state.item); }; - toggleComplete = id => { - let item = this.state.todoList.filter(i => i.id === id)[0] || {}; + toggleComplete = (id) => { + const item = this.state.todoList.filter(i => i.id === id)[0] || {}; if (item.id) { item.complete = !item.complete; this.saveItem(item); } }; - saveItem = updatedItem => { + saveItem = (updatedItem) => { this.setState({ - todoList: this.state.todoList.map(item => - item.id === updatedItem.id ? updatedItem : item - ), - editing: false + todoList: this.state.todoList.map(item => (item.id === updatedItem.id ? updatedItem : item)), + editing: false, }); }; - toggleEdit = id => { - let editing = this.state.editing === id ? false : id; + toggleEdit = (id) => { + const editing = this.state.editing === id ? false : id; this.setState({ editing }); }; @@ -59,31 +60,24 @@ class ToDo extends React.Component {
+ + +
- +
    - {this.state.todoList && - this.state.todoList.map(item => ( -
  • - this.toggleComplete(item.id)}> - {item.text} - - + {this.state.todoList + && this.state.todoList.map(item => ( +
  • + this.toggleComplete(item.id)}>{item.text} +
    Date: Tue, 25 Jun 2019 16:59:03 -0700 Subject: [PATCH 3/7] PR and Travis link in README --- README.md | 50 ++++++++++++++++++++++--------------- src/components/todo/todo.js | 4 ++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ead58e4..067c7b1 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,57 @@ -![CF](http://i.imgur.com/7v5ASc8.png) LAB -================================================= +# ![CF](http://i.imgur.com/7v5ASc8.png) LAB ## Project Name ### Author: Student/Group Name ### Links and Resources -* [submission PR](http://xyz.com) -* [travis](http://xyz.com) -* [back-end](http://xyz.com) (when applicable) -* [front-end](http://xyz.com) (when applicable) + +- [submission PR](https://github.com/401-advanced-javascript-js/lab-33-todo-contextAPI/pull/1) +- [travis](https://travis-ci.com/401-advanced-javascript-js/lab-33-todo-contextAPI) +- [front-end](http://xyz.com) (when applicable) #### Documentation -* [api docs](http://xyz.com) (API servers) -* [jsdoc](http://xyz.com) (Server assignments) -* [styleguide](http://xyz.com) (React assignments) + +- [api docs](http://xyz.com) (API servers) +- [jsdoc](http://xyz.com) (Server assignments) +- [styleguide](http://xyz.com) (React assignments) ### Modules + #### `modulename.js` + ##### Exported Values and Methods ###### `foo(thing) -> string` + Usage Notes or examples ###### `bar(array) -> array` + Usage Notes or examples ### Setup + #### `.env` requirements -* `PORT` - Port Number -* `MONGODB_URI` - URL to the running mongo instance/db + +- `PORT` - Port Number +- `MONGODB_URI` - URL to the running mongo instance/db #### Running the app -* `npm start` -* Endpoint: `/foo/bar/` - * Returns a JSON object with abc in it. -* Endpoint: `/bing/zing/` - * Returns a JSON object with xyz in it. - + +- `npm start` +- Endpoint: `/foo/bar/` + - Returns a JSON object with abc in it. +- Endpoint: `/bing/zing/` + + - Returns a JSON object with xyz in it. + #### Tests -* How do you run tests? -* What assertions were made? -* What assertions need to be / should be made? + +- How do you run tests? +- What assertions were made? +- What assertions need to be / should be made? #### UML + Link to an image of the UML for your application and response to events diff --git a/src/components/todo/todo.js b/src/components/todo/todo.js index 2036bcc..7f1e30f 100755 --- a/src/components/todo/todo.js +++ b/src/components/todo/todo.js @@ -5,7 +5,7 @@ import { When } from '../if'; import CounterWithContext from '../counter/counter-using-context'; import CounterContextProvider from '../context/counter-context'; -import { CounterContext } from '../context/counter-context'; +// import { CounterContext } from '../context/counter-context'; import './todo.scss'; class ToDo extends React.Component { @@ -65,12 +65,14 @@ class ToDo extends React.Component {
+ {/* form */}
+ {/* list */}