summaryrefslogtreecommitdiff
path: root/client/components
diff options
context:
space:
mode:
Diffstat (limited to 'client/components')
-rw-r--r--client/components/App.jsx36
-rw-r--r--client/components/CalorieView.jsx56
-rw-r--r--client/components/LoggedOutView.jsx26
-rw-r--r--client/components/MealView.jsx302
4 files changed, 328 insertions, 92 deletions
diff --git a/client/components/App.jsx b/client/components/App.jsx
index 5a026b4..99c2c11 100644
--- a/client/components/App.jsx
+++ b/client/components/App.jsx
@@ -1,54 +1,52 @@
import React from 'react'
import LoggedOutView from './LoggedOutView.jsx'
-import CalorieView from './CalorieView.jsx'
+import MealView from './MealView.jsx'
-import feathers from 'feathers/client'
-import feathersHooks from 'feathers-hooks'
-import feathersRest from 'feathers-rest/client'
-import feathersAuthentication from 'feathers-authentication/client'
-import superagent from 'superagent'
-
-const rest = feathersRest(window.location.origin)
-
-const client = feathers()
- .configure(feathersHooks())
- .configure(feathersAuthentication({ storage: localStorage }))
- .configure(rest.superagent(superagent))
+import client from '../client'
export default class App extends React.Component {
constructor() {
super()
this.state = {
- ready: true,
+ ready: false,
loggedIn: false,
user: {},
}
client.authenticate()
.then(user => {
- console.log(user)
- this.setState({ ready: true, loggedIn: true, user: user })
+ this.setState({
+ ready: true,
+ loggedIn: true,
+ user: user.data
+ })
})
.catch(error => {
this.setState({ ready: true })
console.error(error)
})
}
+ logOut() {
+ this.setState({
+ user: null,
+ loggedIn: false,
+ })
+ }
render() {
if (this.state.ready) {
if (this.state.loggedIn) {
return (
- <CalorieView client={client} />
+ <MealView user={this.state.user} />
)
}
else {
return (
- <LoggedOutView client={client} />
+ <LoggedOutView />
)
}
}
else {
return (
- <div>LOADING...</div>
+ <div>Loading...</div>
)
}
}
diff --git a/client/components/CalorieView.jsx b/client/components/CalorieView.jsx
deleted file mode 100644
index 3c5fe2d..0000000
--- a/client/components/CalorieView.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react'
-import ModalDialog from './ModalDialog.jsx'
-
-export default class LoggedOutView extends React.Component {
- constructor() {
- super()
- this.state = { modal: null }
-// this.showLogin = this.showLogin.bind(this)
-// this.showSignup = this.showSignup.bind(this)
-// this.closeModal = this.closeModal.bind(this)
- }
-// showLogin() {
-// this.setState({ modal: 'login' })
-// }
-// showSignup() {
-// this.setState({ modal: 'signup' })
-// }
-// closeModal() {
-// this.setState({ modal: '' })
-// }
- render() {
-// const loginVisible = this.state.modal == 'login'
-// const signupVisible = this.state.modal == 'signup'
- return (
- <div>
- LOGGED IN
- </div>
-// <Welcome
-// onLoginClick={this.showLogin}
-// onSignupClick={this.showSignup} />
-// <LoginForm
-// client={this.props.client}
-// visible={loginVisible}
-// onClose={this.closeModal} />
-// <SignupForm
-// client={this.props.client}
-// visible={signupVisible}
-// onClose={this.closeModal} />
- )
- }
-}
-
-
-// export default class UserForm extends React.Component {
-// render() {
-// return (
-// )
-// }
-// }
-//
-// export default class MealForm extends React.Component {
-// render() {
-// return (
-// )
-// }
-// }
diff --git a/client/components/LoggedOutView.jsx b/client/components/LoggedOutView.jsx
index e058455..f217143 100644
--- a/client/components/LoggedOutView.jsx
+++ b/client/components/LoggedOutView.jsx
@@ -1,5 +1,6 @@
import React from 'react'
import ModalDialog from './ModalDialog.jsx'
+import client from '../client'
export default class LoggedOutView extends React.Component {
constructor() {
@@ -27,11 +28,9 @@ export default class LoggedOutView extends React.Component {
onLoginClick={this.showLogin}
onSignupClick={this.showSignup} />
<LoginForm
- client={this.props.client}
visible={loginVisible}
onClose={this.closeModal} />
<SignupForm
- client={this.props.client}
visible={signupVisible}
onClose={this.closeModal} />
</div>
@@ -76,15 +75,13 @@ class LoginForm extends React.Component {
}
handleSubmit(event) {
event.preventDefault()
- this.props.client.authenticate({
+ client.authenticate({
type: 'local',
email: this.state.email,
password: this.state.password,
}).then(res => {
console.log('Authenticated!', res);
- // this.props.client.set('user', res.data)
- // something in this library is hardcoded accessToken
- // return this.props.client.passport.setJWT(res.token)
+ window.location.reload()
}).catch(error => {
console.error('Error authenticating!', error);
this.setState({
@@ -138,23 +135,18 @@ class SignupForm extends React.Component {
}
handleSubmit(event) {
event.preventDefault()
- const usersService = this.props.client.service('users')
+ const usersService = client.service('users')
usersService.create(this.state).then(result => {
- return this.props.client.authenticate({
+ return client.authenticate({
strategy: 'local',
email: this.state.email,
password: this.state.password,
})
- })
- .then(res => {
- this.props.client.set('user', res.data)
- this.props.client.set('token', res.accessToken)
- return client.passport.verifyJWT(res.accessToken)
- })
- .then(payload => {
- console.log(payload)
+ }).then(res => {
+ console.log('Authenticated!', res)
+ window.location.reload()
}).catch(error => {
- console.error(error)
+ console.error('Error authenticating!', error)
this.setState({
error: error.toString()
})
diff --git a/client/components/MealView.jsx b/client/components/MealView.jsx
new file mode 100644
index 0000000..920dca9
--- /dev/null
+++ b/client/components/MealView.jsx
@@ -0,0 +1,302 @@
+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>
+ )
+ }
+}
+
+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 {
+ constructor(props) {
+ super()
+
+ this.state = {
+ total: 0,
+ limit: 0,
+ skip: 0,
+ data: []
+ }
+
+ this.handleCreate = this.handleCreate.bind(this)
+ this.handleUpdate = this.handleUpdate.bind(this)
+ this.pickMeal = this.pickMeal.bind(this)
+
+ client.service('meals').find({
+ query: {
+ userid: props.user.id,
+ '$sort': { 'date': '-1' },
+ token: client.get('token'),
+ },
+ }).then((data) => {
+ console.log(data)
+ this.setState(data)
+ }).catch((error) => {
+ console.error(error)
+ })
+ }
+ handleCreate(meal) {
+ const meals = this.state.data.slice()
+ meals.unshift( meal )
+ this.setState({
+ data: meals.sort(sortByDate)
+ })
+ }
+ handleUpdate(meal) {
+ const meals = this.state.data.map((data, i) => {
+ return (data.id == meal.id) ? meal : data
+ }).sort(sortByDate)
+ this.setState({
+ data: meals
+ })
+ }
+ pickMeal(meal) {
+ this.mealForm.pick(meal)
+ }
+ render() {
+ console.log(this.state.data)
+ const items = this.state.data.map((meal, i) => {
+ return (
+ <MealItem key={meal.id}
+ meal={meal}
+ onClick={this.pickMeal} />
+ )
+ })
+ return (
+ <div>
+ <MealForm user={this.props.user}
+ ref={(mealForm) => { this.mealForm = mealForm }}
+ onCreate={(meal) => { this.handleCreate(meal) }}
+ onUpdate={(meal) => { this.handleUpdate(meal) }}
+ />
+ <div>
+ {items}
+ </div>
+ </div>
+ )
+ }
+}
+
+class MealItem extends React.Component {
+ render() {
+ const meal = this.props.meal
+ const date = parseDate(meal.date)
+ const time = parseTime(meal.time)
+ return (
+ <div className='meal' 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>
+ )
+ }
+}
+
+class MealForm extends React.Component {
+ constructor(props) {
+ super()
+ this.state = {
+ id: '',
+ userid: props.user.id,
+ name: '',
+ calories: '',
+ date: new Date (),
+ time: new Date (),
+ }
+ this.updateState = this.updateState.bind(this)
+ this.handleSubmit = this.handleSubmit.bind(this)
+ }
+ reset() {
+ this.setState({
+ id: '',
+ name: '',
+ calories: '',
+ date: new Date (),
+ time: new Date (),
+ })
+ }
+ pick(meal){
+ console.log(meal)
+ this.setState(meal)
+ }
+ updateState(event){
+ const name = event.target.name
+ let value = event.target.value
+ if (name === 'date') {
+ value = new Date(value).toString()
+ } else if (name === 'time') {
+ value = new Date('1970-01-01T' + value).toString()
+ } else if (name === 'calories') {
+ value = parseInt(value)
+ }
+ this.setState({
+ [name]: value,
+ error: null,
+ })
+ }
+ handleSubmit(event) {
+ event.preventDefault()
+
+ const id = this.state.id
+
+ if (! id) {
+ this.create()
+ }
+ else {
+ this.update()
+ }
+ }
+ create() {
+ const mealsService = client.service('meals')
+ const params = { query: { token: client.get('token') } }
+
+ mealsService.create(this.state, params).then(result => {
+ console.log(result)
+ this.props.onCreate(result)
+ this.reset()
+ }).catch(error => {
+ console.error(error)
+ this.setState({
+ error: error.toString()
+ })
+ })
+ }
+ update() {
+ const mealsService = client.service('meals')
+ const params = { query: { token: client.get('token') } }
+
+ mealsService.update(this.state.id, this.state, params).then(result => {
+ console.log(result)
+ this.props.onUpdate(result)
+ this.reset()
+ }).catch(error => {
+ console.error(error)
+ this.setState({
+ error: error.toString()
+ })
+ })
+ }
+ render() {
+ const id = this.state.id
+ const action = id ? 'update' : 'create'
+
+ const date = parseDate(this.state.date)
+ const time = parseTime(this.state.time)
+ return (
+ <form onSubmit={this.handleSubmit} className={action}>
+ <input type='hidden' name='id' value={this.state.id} readOnly />
+ <input type='hidden' name='userid' value={this.state.userid} readOnly />
+ <input type='text' name='name' placeholder='Name' value={this.state.name} required onChange={this.updateState} />
+ <input type='number' name='calories' placeholder='Calories' value={this.state.calories} required onChange={this.updateState} min='0' max='10000' />
+ <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>
+ <div className='error'>{this.state.error}</div>
+ </form>
+ )
+ }
+}
+
+function sortByDate(a,b){
+ return new Date(b.date) - new Date(a.date)
+}
+
+function parseDate(d){
+ return new Date(d).toISOString().substr(0, 10)
+}
+
+function parseTime(d){
+ return new Date(d).toISOString().substr(11, 5)
+}
+
+function capitalize(s){
+ s = s || '';
+ return (s[0] || '').toUpperCase() + s.substr(1)
+}
+
+class UserList extends React.Component {
+ render() {
+ const items = []
+ return (
+ <div>
+ {items}
+ </div>
+ )
+ }
+}