Compare commits

...

2 Commits

Author SHA1 Message Date
a915b36967 implemented user login and logout 2019-07-08 14:31:51 -04:00
337b12ad29 WIP refactor notes, ProjectView 2019-07-08 09:35:18 -04:00
6 changed files with 177 additions and 23 deletions

View File

@ -0,0 +1,19 @@
# TODO for refactoring
- update renderProject to renderProjectView
- update renderProjects to renderProjectsView
- create ProjectsView, ProjectTasksView, UserProjectsView
- create TasksView, UserTasksView
# User Stories
As a user, I want to:
- View all available projects (should we assume all is public for now?)
- View all available tasks
- View all available profiles (e.g., to find potential collaborators)
- View a single project with its tasks (including unassigned)
- View a single profile with tasks assigned (to see my tasks, to see anothers' tasks)
- Hide completed tasks

View File

@ -19,6 +19,7 @@ import {
import { updateProfile } from './controllers/profile'
import {
Login,
About,
Tasks,
UpdateTask,
@ -33,7 +34,7 @@ console.log('Using API at ' + API)
const defaultState = {
loading: true,
user: { name: 'Scott' },
user: {},
tasks: [],
projects: [],
component: 'projects',
@ -52,6 +53,8 @@ class App extends React.Component {
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.login = this.login.bind(this)
this.createTask = createTask.bind(this)
this.updateTask = updateTask.bind(this)
this.deleteTask = deleteTask.bind(this)
@ -86,6 +89,19 @@ class App extends React.Component {
}
}
async login(userData) {
try {
const { data } = await axios.post(API + '/login', userData)
console.log('login retrieved data:', data)
if (data.name) {
this.setState({ user: data })
this.navigate('projects')
} else this.setState({ error: 'no user found.' })
} catch (err) {
console.log(err)
}
}
async fetchData() {
const tasks = await this.fetchTasks()
const projects = await this.fetchProjects()
@ -112,22 +128,26 @@ class App extends React.Component {
return <div>Loading...</div>
}
renderError() {
if (this.state.error.message === 'Network Error') {
alert(`Failed to reach backend at\n${this.state.error.config.url}.`)
} else {
return (
<div>
There was an error: {this.state.error.message}
<ul>
{Object.keys(this.state.error.config).map(key => (
<li>
{key}: {JSON.stringify(this.state.error.config[key])}
</li>
))}
</ul>
</div>
)
const { error } = this.state
if (error) {
if (this.state.error.message === 'Network Error') {
alert(`Failed to reach backend at\n${this.state.error.config.url}.`)
} else {
return (
<div>
There was an error: {this.state.error.message}
<ul>
{Object.keys(this.state.error.config).map(key => (
<li>
{key}: {JSON.stringify(this.state.error.config[key])}
</li>
))}
</ul>
</div>
)
}
}
return <div>Uncaught error. You probably forgot to render something.</div>
}
renderProfile() {
return (
@ -170,6 +190,10 @@ class App extends React.Component {
renderAbout() {
return <About {...this.state} />
}
renderLogin() {
return <Login login={this.login} {...this.state} />
}
renderTasks(filtered, completed) {
return (
<Tasks
@ -229,6 +253,8 @@ class App extends React.Component {
? this.renderProjects()
: this.state.component === 'project'
? this.renderProject()
: this.state.component === 'login'
? this.renderLogin()
: this.renderError()
return (

View File

@ -0,0 +1,23 @@
import React from 'react'
import Tasks from './tasks'
function Project(props) {
// if (!props.selectedProjectId) {
// props.navigate('projects')
// return null
// }
// const project = props.projects.find(p => p.id === props.selectedProjectId)
// const filtered = props.tasks.filter(t => t.projectId === props.selectedProjectId && !t.completed)
// const completed = props.tasks.filter(
// t => (t.projectId === props.selectedProjectId && t.completed === true) || null,
// )
return (
<div>
<h2>{props.project.name}</h2>
<Tasks filtered={props.filtered} completed={props.completed} {...props} />
</div>
)
}
export default Project

View File

@ -1,3 +1,4 @@
export { default as Login } from './login'
export { default as Navbar } from './navbar'
export { default as About } from './about'
export { default as Tasks } from './tasks'

62
src/components/login.js Normal file
View File

@ -0,0 +1,62 @@
import React from 'react'
const initialState = { email: '', password: '' }
class Login extends React.Component {
constructor() {
super()
this.state = initialState
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value })
}
handleSubmit(e) {
e.preventDefault()
this.setState(initialState)
const email = e.target.email.value
const password = e.target.password.value // hash dis b4 send on frontend
return this.props.login({ email, password })
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="form-group row">
<label htmlFor="email" className="col-sm-2 col-form-label">
Email
</label>
<div className="col-sm-10">
<input
type="email"
className="form-control"
id="email"
placeholder="Email"
/>
</div>
</div>
<div className="form-group row">
<label htmlFor="password" className="col-sm-2 col-form-label">
Password
</label>
<div className="col-sm-10">
<input
type="password"
className="form-control"
id="password"
placeholder="Password"
/>
</div>
</div>
<button type="submit" onSubmit={this.handleSubmit}>
Log In
</button>
</form>
)
}
}
export default Login

View File

@ -3,13 +3,23 @@ import React from 'react'
function Navbar(props) {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a
className="navbar-brand"
href="#profile"
onClick={() => props.navigate('profile')}
>
{`Hello, ${props.user.name}!`}
</a>
{props.user && props.user.name ? (
<a
className="navbar-brand"
href="#profile"
onClick={() => props.navigate('profile')}
>
{`Hello, ${props.user.name}!`}
</a>
) : (
<a
className="navbar-brand"
href="#login"
onClick={() => props.navigate('login')}
>
Log in
</a>
)}
<button
className="navbar-toggler"
type="button"
@ -53,6 +63,19 @@ function Navbar(props) {
About
</a>
</li>
{props.user && props.user.name ? (
<li className="nav-item" onClick={() => props.logout()}>
<a className="nav-link" href="#logout">
Logout
</a>
</li>
) : (
<li className="nav-item" onClick={() => props.navigate('login')}>
<a className="nav-link" href="#login">
Login
</a>
</li>
)}
</ul>
</div>
</nav>