Api & Client: add an activity

This commit is contained in:
Sam 2018-05-01 19:29:21 +02:00
parent efd076aa41
commit c553a5a8d3
7 changed files with 170 additions and 0 deletions

View File

@ -95,6 +95,7 @@ def post_activity(auth_user_id):
new_activity.ascent = gpx_data['uphill'] new_activity.ascent = gpx_data['uphill']
new_activity.max_speed = gpx_data['max_speed'] new_activity.max_speed = gpx_data['max_speed']
new_activity.ave_speed = gpx_data['average_speed'] new_activity.ave_speed = gpx_data['average_speed']
db.session.add(new_activity)
db.session.commit() db.session.commit()
response_object = { response_object = {

View File

@ -0,0 +1,19 @@
import mpwoApi from '../mwpoApi/activities'
import { history } from '../index'
import { setError } from './index'
export function addActivity(form) {
return function(dispatch) {
return mpwoApi
.addActivity(form)
.then(ret => {
if (ret.status === 'created') {
history.push('/')
} else {
dispatch(setError(`activities: ${ret.message}`))
}
})
.catch(error => dispatch(setError(`activities: ${error}`)))
}
}

View File

@ -0,0 +1,114 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import { connect } from 'react-redux'
import { addActivity } from '../../actions/activities'
import { getData } from '../../actions/index'
import { history } from '../../index'
class AddActivity extends React.Component {
componentDidMount() {
this.props.loadSports()
}
render() {
const { message, onAddSport, sports } = this.props
return (
<div>
<Helmet>
<title>mpwo - Add an activity</title>
</Helmet>
<br /><br />
{message && (
<code>{message}</code>
)}
<div className="container">
<div className="row">
<div className="col-md-2" />
<div className="col-md-8">
<div className="card add-activity">
<h2 className="card-header text-center">
Add a sport
</h2>
<div className="card-body">
<form
encType="multipart/form-data"
method="post"
onSubmit={event => event.preventDefault()}
>
<div className="form-group">
<label>
Sport:
<select
className="form-control input-lg"
name="sport"
required
>
<option value="" />
{sports.map(sport => (
<option key={sport.id} value={sport.id}>
{sport.label}
</option>
))}
</select>
</label>
</div>
<div className="form-group">
<label>
GPX file:
<input
accept=".gpx"
className="form-control input-lg"
name="gpxFile"
required
type="file"
/>
</label>
</div>
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
onClick={event => onAddSport(event)}
value="Submit"
/>
<input
type="submit"
className="btn btn-secondary btn-lg btn-block"
onClick={() => history.go(-1)}
value="Cancel"
/>
</form>
</div>
</div>
</div>
<div className="col-md-2" />
</div>
</div>
</div>
)
}
}
export default connect(
state => ({
message: state.message,
sports: state.sports.data,
user: state.user,
}),
dispatch => ({
loadSports: () => {
dispatch(getData('sports'))
},
onAddSport: event => {
const form = new FormData()
form.append('file', event.target.form.gpxFile.files[0])
form.append(
'data', `{"sport_id": ${event.target.form.sport.value}}`
)
dispatch(addActivity(form))
},
})
)(AddActivity)

View File

@ -56,3 +56,7 @@ input, textarea {
margin: 1em; margin: 1em;
text-align: center; text-align: center;
} }
.add-activity {
margin-top: 50px;
}

View File

@ -3,6 +3,7 @@ import { Redirect, Route, Switch } from 'react-router-dom'
import './App.css' import './App.css'
import Admin from './Admin' import Admin from './Admin'
import AddWorkout from './Activities/AddActivity'
import Dashboard from './Dashboard' import Dashboard from './Dashboard'
import Logout from './User/Logout' import Logout from './User/Logout'
import NavBar from './NavBar' import NavBar from './NavBar'
@ -83,6 +84,7 @@ export default class App extends React.Component {
) )
)} )}
/> />
<Route exact path="/activities/add" component={AddWorkout} />
<Route path="/admin" component={Admin} /> <Route path="/admin" component={Admin} />
<Route component={NotFound} /> <Route component={NotFound} />
</Switch> </Switch>

View File

@ -33,6 +33,18 @@ function NavBar (props) {
Dashboard Dashboard
</Link> </Link>
</li> </li>
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/activities/add',
}}
>
Add a workout
</Link>
</li>
)}
{props.user.isAdmin && ( {props.user.isAdmin && (
<li className="nav-item"> <li className="nav-item">
<Link <Link

View File

@ -0,0 +1,18 @@
import { apiUrl } from '../utils'
export default class MpwoApi {
static addActivity(formData) {
const request = new Request(`${apiUrl}activities`, {
method: 'POST',
headers: new Headers({
Authorization: `Bearer ${window.localStorage.getItem('authToken')}`,
}),
body: formData,
})
return fetch(request)
.then(response => response.json())
.catch(error => error)
}
}