diff options
Diffstat (limited to 'client')
| -rw-r--r-- | client/client.js | 3 | ||||
| -rw-r--r-- | client/components/App.jsx | 4 | ||||
| -rw-r--r-- | client/components/LoggedInView.jsx | 110 | ||||
| -rw-r--r-- | client/components/LoggedOutView.jsx | 3 | ||||
| -rw-r--r-- | client/components/MealFilter.jsx | 113 | ||||
| -rw-r--r-- | client/components/MealList.jsx (renamed from client/components/MealView.jsx) | 118 | ||||
| -rw-r--r-- | client/components/UserList.jsx | 75 | ||||
| -rw-r--r-- | client/index.js | 15 |
8 files changed, 330 insertions, 111 deletions
diff --git a/client/client.js b/client/client.js index 1ed895c..07c3158 100644 --- a/client/client.js +++ b/client/client.js @@ -9,5 +9,6 @@ const client = feathers() .configure(feathersHooks()) .configure(feathersAuthentication({ storage: localStorage })) .configure(rest.superagent(superagent)) -module.exports = client + +export default client diff --git a/client/components/App.jsx b/client/components/App.jsx index 99c2c11..046ce72 100644 --- a/client/components/App.jsx +++ b/client/components/App.jsx @@ -1,6 +1,6 @@ import React from 'react' import LoggedOutView from './LoggedOutView.jsx' -import MealView from './MealView.jsx' +import LoggedInView from './LoggedInView.jsx' import client from '../client' @@ -35,7 +35,7 @@ export default class App extends React.Component { if (this.state.ready) { if (this.state.loggedIn) { return ( - <MealView user={this.state.user} /> + <LoggedInView user={this.state.user} /> ) } else { diff --git a/client/components/LoggedInView.jsx b/client/components/LoggedInView.jsx new file mode 100644 index 0000000..5c7a690 --- /dev/null +++ b/client/components/LoggedInView.jsx @@ -0,0 +1,110 @@ +import React from 'react' +import ModalDialog from './ModalDialog.jsx' +import UserList from './UserList.jsx' +import MealList from './MealList.jsx' + +import client from '../client' + +export default class LoggedInView extends React.Component { + constructor(props) { + super() + this.state = { + user: Object.assign({}, props.user), + mode: 'meals', + } + this.updateUser = this.updateUser.bind(this) + this.toggleMode = this.toggleMode.bind(this) + } + toggleMode(){ + this.state.mode = this.state.mode == 'meals' ? 'users' : 'meals' + } + updateUser(user) { + this.setState({ + user: user + }) + } + render() { + let activity = null + if (this.state.mode == 'meals') { + activity = (<MealList user={this.state.user} currentUser={this.props.user} />) + } + else { + activity = (<UserList user={this.state.user} currentUser={this.props.user} updateUser={this.updateUser} />) + } + return ( + <div> + <Menu mode={this.state.mode} + user={this.state.user} + toggleMode={this.toggleMode} + currentUser={this.props.user} + updateUser={this.updateUser} /> + {activity} + </div> + ) + } +} + + +class Menu extends React.Component { + constructor() { + super() + this.setGoal = this.setGoal.bind(this) + this.logout = this.logout.bind(this) + } + setGoal() { + const goal = Math.abs(parseInt(prompt('Please enter your calorie goal', this.props.user.goal))) + if (goal) { + client.service('users').patch(this.props.user.id, { + goal: goal, + token: client.get('token'), + }).then((user) => { + this.props.updateUser(user) + }) + } + } + logout() { + client.logout().then(() => { + window.location.reload() + }) + } + render() { + const user = this.props.user + const items = [] + items.push( <li key='hello'>Hello {user.email}</li> ) + items.push( <li key='goal'><a href='#' onClick={this.setGoal}>Goal</a>: {user.goal}</li> ) + switch (user.role) { + case 'admin': + if (this.props.user.id !== this.props.currentUser.id) { + items.push( <li key='resetUser'><a href='#' onClick={this.resetUser}>Reset User</a></li> ) + } + items.push( <li key='userlist'><a href='#' onClick={this.props.toggleMode}>Users</a></li> ) + items.push( <li key='userlist'><a href='#' onClick={this.props.toggleMode}>Meals</a></li> ) + break + case 'manager': + items.push( <li key='userlist'><a href='#' onClick={this.props.toggleMode}>Users</a></li> ) + items.push( <li key='userlist'><a href='#' onClick={this.props.toggleMode}>Meals</a></li> ) + case 'user': + break + } + items.push( <li key='logout'><a href='#' onClick={this.logout}>Logout</a></li> ) + + return ( + <div> + <ul className='menu'> + {items} + </ul> + </div> + ) + // <ProfileModal user={user} visible={false} onClose={() => {}} /> + } +} + + +// class ProfileModal extends React.Component { +// render() { +// return ( +// <ModalDialog visible={this.props.visible} onClose={this.props.onClose}> +// </ModalDialog> +// ) +// } +// } diff --git a/client/components/LoggedOutView.jsx b/client/components/LoggedOutView.jsx index f217143..0773059 100644 --- a/client/components/LoggedOutView.jsx +++ b/client/components/LoggedOutView.jsx @@ -137,8 +137,9 @@ class SignupForm extends React.Component { event.preventDefault() const usersService = client.service('users') usersService.create(this.state).then(result => { + console.log(result) return client.authenticate({ - strategy: 'local', + type: 'local', email: this.state.email, password: this.state.password, }) diff --git a/client/components/MealFilter.jsx b/client/components/MealFilter.jsx new file mode 100644 index 0000000..cd78f89 --- /dev/null +++ b/client/components/MealFilter.jsx @@ -0,0 +1,113 @@ +import React from 'react' + +import client from '../client' + +import moment from 'moment' + +import { DateRange } from 'react-date-range'; + +export default class MealFilter extends React.Component { + constructor(){ + super() + const start = new Date () + const end = new Date () + end.setDate(end.getDate()-6) + this.state = { + startDate: moment(start), + endDate: moment(end), + startTime: 0, + endTime: 23, + } + this.handleSelect = this.handleSelect.bind(this) + } + handleSelect(range){ + console.log(range) + // range.startDate; // Momentjs object + // range.endDate + this.setState(range) + } + pickTimeRange(event,start,end){ + this.setState({startTime: start, endTime: end}) + } + + render(){ + var times = [ + [0, 11, 'Breakfast'], + [12, 15, 'Lunch'], + [15, 23, 'Dinner'], + [0, 23, 'All'], + ].map( (r,i) => { + const start = r[0] + const end = r[1] + const name = r[2] + let className = '' + if (this.state.startTime === start && this.state.endTime === end) { + className = 'selected' + } + return ( + <button + key={i} + className={className} + onClick={(e) => {this.pickTimeRange(e,start,end)}}> + {name} + </button> + ) + }) + return ( + <div> + <DateRange + onInit={this.handleSelect} + onChange={this.handleSelect} + startDate={this.state.startDate} + endDate={this.state.endDate} + /> + {times} + </div> + ) + } +} + + +// class MealFilter extends React.Component { +// constructor(props){ +// super() +// this.state = { +// fromDate: new Date (), +// toDate: new Date (), +// fromTime: new Date (), +// toTime: new Date (), +// } +// this.updateState = this.updateState.bind(this) +// } +// updateState(e){ +// const name = event.target.name +// let value = event.target.value +// if (name === 'date') { +// value = new Date(value + 'T' + this.state.date.split("T")[1] ).toString() +// } else if (name === 'time') { +// value = new Date(this.state.date.split("T")[0] + value).toString() +// } +// this.setState({ +// [name]: value, +// error: null, +// }) +// } +// render () { +// const fromDate = parseDate(this.state.fromDate) +// const toDate = parseDate(this.state.toDate) +// const fromTime = parseTime(this.state.fromTime) +// const toTime = parseTime(this.state.toTime) +// return ( +// <div> +// Filter by date: +// <input type='date' name='fromDate' placeholder='From date' value={fromDate} required onChange={this.updateState} /> +// to +// <input type='date' name='toDate' placeholder='To date' value={toDate} required onChange={this.updateState} /> +// and from time +// <input type='time' name='fromTime' placeholder='From iime' value={fromTime} required onChange={this.updateState} step='3600' /> +// to +// <input type='time' name='toTime' placeholder='To time' value={toTime} required onChange={this.updateState} step='3600' /> +// </div> +// ) +// } +// } diff --git a/client/components/MealView.jsx b/client/components/MealList.jsx index ab8cebf..53c8289 100644 --- a/client/components/MealView.jsx +++ b/client/components/MealList.jsx @@ -1,87 +1,10 @@ import React from 'react' -import ModalDialog from './ModalDialog.jsx' import client from '../client' -export default class MealView extends React.Component { - constructor(props) { - super() - this.state = { - user: Object.assign({}, props.user), - meals: [], - } - this.updateUser = this.updateUser.bind(this) - } - updateUser(user) { - this.setState({ - user: user - }) - } - render() { - const user = this.state.user - const meals = this.state.meals - return ( - <div> - <Menu user={user} currentUser={this.props.user} updateUser={this.updateUser} /> - <MealList user={user} currentUser={this.props.user} /> - <div className='users'> - <UserList /> - </div> - </div> - ) - } -} +import MealFilter from './MealFilter.jsx' -class Menu extends React.Component { - constructor() { - super() - this.setGoal = this.setGoal.bind(this) - this.logout = this.logout.bind(this) - } - setGoal() { - const goal = Math.abs(parseInt(prompt('Please enter your calorie goal', this.props.user.goal))) - if (goal) { - client.service('users').patch(this.props.user.id, { - goal: goal, - token: client.get('token'), - }).then((user) => { - this.props.updateUser(user) - }) - } - } - logout() { - client.logout().then(() => { - window.location.reload() - }) - } - render() { - const user = this.props.user - const items = [] - items.push( <li key='hello'>Hello {user.email}</li> ) - items.push( <li key='goal'><a href='#' onClick={this.setGoal}>Goal</a>: {user.goal}</li> ) - items.push( <li key='logout'><a href='#' onClick={this.logout}>Logout</a></li> ) - - return ( - <div> - <ul className='menu'> - {items} - </ul> - <ProfileModal user={user} visible={false} onClose={() => {}} /> - </div> - ) - } -} - -class ProfileModal extends React.Component { - render() { - return ( - <ModalDialog visible={this.props.visible} onClose={this.props.onClose}> - </ModalDialog> - ) - } -} - -class MealList extends React.Component { +export default class MealList extends React.Component { constructor(props) { super() @@ -117,7 +40,7 @@ class MealList extends React.Component { }) } handleUpdate(meal) { - const meals = this.state.data.map((data, i) => { + const meals = this.state.data.map((data) => { return (data.id === meal.id) ? meal : data }).sort(sortByDate) this.setState({ @@ -125,7 +48,7 @@ class MealList extends React.Component { }) } handleDelete(mealid) { - const meals = this.state.data.filter((data, i) => { + const meals = this.state.data.filter((data) => { return data.id !== mealid }).sort(sortByDate) this.setState({ @@ -136,7 +59,7 @@ class MealList extends React.Component { this.mealForm.pick(meal) } render() { - const items = this.state.data.map((meal, i) => { + const items = this.state.data.map((meal) => { return ( <MealItem key={meal.id} meal={meal} @@ -144,6 +67,11 @@ class MealList extends React.Component { onDelete={this.handleDelete} /> ) }) + if (! items.length) { + items.push( + <div className='quiet' key='nomeals'>No meals found</div> + ) + } return ( <div> <MealForm user={this.props.user} @@ -151,6 +79,7 @@ class MealList extends React.Component { onCreate={(meal) => { this.handleCreate(meal) }} onUpdate={(meal) => { this.handleUpdate(meal) }} /> + <MealFilter /> <div> {items} </div> @@ -180,9 +109,9 @@ class MealItem extends React.Component { // const canEdit = this.props.meal.userid === this.props.currentUser.id ? 'canEdit' : '' const canEdit = 'canEdit' const date = parseDate(meal.date) - const time = parseTime(meal.time) + const time = parseTime(meal.date) return ( - <div className={'meal ' + canEdit} onClick={() => this.props.onClick(meal)}> + <div className={'meal row ' + canEdit} onClick={() => this.props.onClick(meal)}> <div className='name'>{meal.name}</div> <div className='calories'>{meal.calories} cal</div> <div className='date'>{date}</div> @@ -202,7 +131,6 @@ class MealForm extends React.Component { name: '', calories: '', date: new Date (), - time: new Date (), } this.updateState = this.updateState.bind(this) this.handleSubmit = this.handleSubmit.bind(this) @@ -213,7 +141,6 @@ class MealForm extends React.Component { name: '', calories: '', date: new Date (), - time: new Date (), }) } pick(meal){ @@ -223,9 +150,9 @@ class MealForm extends React.Component { const name = event.target.name let value = event.target.value if (name === 'date') { - value = new Date(value).toString() + value = new Date(value + 'T' + this.state.date.split("T")[1] ).toString() } else if (name === 'time') { - value = new Date('1970-01-01T' + value).toString() + value = new Date(this.state.date.split("T")[0] + value).toString() } else if (name === 'calories') { value = parseInt(value) } @@ -249,6 +176,7 @@ class MealForm extends React.Component { create() { const mealsService = client.service('meals') const params = { query: { token: client.get('token') } } + mealsService.create(this.state, params).then(result => { this.props.onCreate(result) this.reset() @@ -278,7 +206,7 @@ class MealForm extends React.Component { const action = id ? 'update' : 'create' const date = parseDate(this.state.date) - const time = parseTime(this.state.time) + const time = parseTime(this.state.date) return ( <form onSubmit={this.handleSubmit} className={action}> <input type='hidden' name='id' value={this.state.id} readOnly /> @@ -288,7 +216,7 @@ class MealForm extends React.Component { <input type='date' name='date' placeholder='Date' value={date} required onChange={this.updateState} /> <input type='time' name='time' placeholder='Time' value={time} required onChange={this.updateState} step='60' /> <input type='submit' value={capitalize(action)} /> - <span className='clear' onClick={() => this.reset()}>clear</span> + <span className='clear' onClick={() => this.reset()}>cancel</span> <div className='error'>{this.state.error}</div> </form> ) @@ -312,13 +240,3 @@ function capitalize(s){ return (s[0] || '').toUpperCase() + s.substr(1) } -class UserList extends React.Component { - render() { - const items = [] - return ( - <div> - {items} - </div> - ) - } -} diff --git a/client/components/UserList.jsx b/client/components/UserList.jsx new file mode 100644 index 0000000..fb93b9f --- /dev/null +++ b/client/components/UserList.jsx @@ -0,0 +1,75 @@ +import React from 'react' + +import client from '../client' + +export default class UserList extends React.Component { + constructor(props){ + super() + console.log("WHAT") + this.state = { + users: [], + } +// client.service('users').find({ +// query: { +// '$sort': { 'date': '-1' }, +// token: client.get('token'), +// }, +// }).then((data) => { +// this.setState(data) +// }).catch((error) => { +// console.error(error) +// }) + this.pick.bind(this) + } + pick(){ + } + render() { + const items = this.state.users.map((item,i) => { + return ( + <UserItem key={user.id} + user={user} + onClick={this.pick} + onDelete={this.handleDelete} /> + ) + }) + return ( + <div> + {items} + </div> + ) + } +} + +class UserItem extends React.Component { + constructor() { + super() + this.remove = this.remove.bind(this) + } + remove(e) { + e.stopPropagation() + const userid = this.props.user.id + const usersService = client.service('users') + const params = { query: { token: client.get('token') } } + usersService.remove(userid, params).then(result => { + this.props.onDelete(userid) + }).catch(error => { + console.error(error) + }) + } + render() { + const user = this.props.user + // const canEdit = this.props.user.userid === this.props.currentUser.id ? 'canEdit' : '' + const canEdit = 'canEdit' + const date = parseDate(meal.date) + const time = parseTime(meal.date) + return ( + <div className={'user row ' + canEdit} onClick={() => this.props.onClick(meal)}> + <div className='name'>{meal.name}</div> + <div className='calories'>{meal.calories} cal</div> + <div className='date'>{date}</div> + <div className='time'>{time}</div> + <div className='remove' onClick={this.remove}>x</div> + </div> + ) + } +} diff --git a/client/index.js b/client/index.js index 55792c6..61e61ad 100644 --- a/client/index.js +++ b/client/index.js @@ -1,14 +1,15 @@ -import React from 'react'; + +import React from 'react' import ReactDOM from 'react-dom'; import App from './components/App.jsx'; -const is_iphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) -const is_ipad = (navigator.userAgent.match(/iPad/i)) -const is_android = (navigator.userAgent.match(/Android/i)) -const is_mobile = is_iphone || is_ipad || is_android -const is_desktop = ! is_mobile +const isIphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) +const isIpad = (navigator.userAgent.match(/iPad/i)) +const isAndroid = (navigator.userAgent.match(/Android/i)) +const isMobile = isIphone || isIpad || isAndroid +const isDesktop = ! isMobile -document.body.classList.add(is_desktop ? 'desktop' : 'mobile') +document.body.classList.add(isDesktop ? 'desktop' : 'mobile') ReactDOM.render(<App />, document.getElementById('container')); |
