API & Client: fix and update (pagination, style)

This commit is contained in:
Sam 2018-05-17 13:33:44 +02:00
parent ca80a8b6d5
commit f744eb0769
9 changed files with 128 additions and 122 deletions

View File

@ -160,6 +160,20 @@ class Activity(db.Model):
self.duration = duration
def serialize(self):
previous_activity = Activity.query.filter(
Activity.id != self.id,
Activity.user_id == self.user_id,
Activity.activity_date <= self.activity_date
).order_by(
Activity.activity_date.desc()
).first()
next_activity = Activity.query.filter(
Activity.id != self.id,
Activity.user_id == self.user_id,
Activity.activity_date >= self.activity_date
).order_by(
Activity.activity_date.asc()
).first()
return {
"id": self.id,
"user_id": self.user_id,
@ -180,6 +194,8 @@ class Activity(db.Model):
"ave_speed": float(self.ave_speed) if self.ave_speed else None,
"with_gpx": self.gpx is not None,
"bounds": [float(bound) for bound in self.bounds] if self.bounds else [], # noqa
"previous_activity": previous_activity.id if previous_activity else None, # noqa
"next_activity": next_activity.id if next_activity else None,
"segments": [segment.serialize() for segment in self.segments],
"records": [record.serialize() for record in self.records]
}

View File

@ -3,11 +3,6 @@ import mpwoApi from '../mwpoApi/activities'
import { history } from '../index'
import { setError } from './index'
export const endPagination = status => ({
type: 'END_PAGINATION',
status,
})
export const pushActivities = activities => ({
type: 'PUSH_ACTIVITIES',
activities,
@ -90,9 +85,6 @@ export const getMoreActivities = page => dispatch => mpwoGenericApi
if (ret.data.activities.length > 0) {
dispatch(pushActivities(ret.data.activities))
}
if (ret.data.activities.length < 5) {
dispatch(endPagination(true))
}
} else {
dispatch(setError(`activities: ${ret.message}`))
}

View File

@ -51,7 +51,7 @@ class ActivityDisplay extends React.Component {
}}
close={() => this.setState({ displayModal: false })}
/>}
{activity && sport && (
{activity && sport && activities.length === 1 && (
<div className="row">
<div className="col">
<div className="card">
@ -194,11 +194,11 @@ export default connect(
user: state.user,
}),
dispatch => ({
onDeleteActivity: activityId => {
dispatch(deleteActivity(activityId))
},
loadActivity: activityId => {
dispatch(getData('activities', activityId))
},
onDeleteActivity: activityId => {
dispatch(deleteActivity(activityId))
},
})
)(ActivityDisplay)

View File

@ -8,6 +8,10 @@ class AdminSports extends React.Component {
componentDidMount() {
this.props.loadSport(this.props.match.params.sportId)
}
componentWillUnmount() {
// reload all Sports
this.props.loadSport(null)
}
render() {
const { sports } = this.props

View File

@ -1,4 +1,6 @@
.App {
background-color: #eaeaea;
min-height: 100vh;
text-align: center;
}
@ -99,7 +101,7 @@ input, textarea {
border-radius: 5px;
max-width: 500px;
margin: 20% auto;
z-index: 100;
z-index: 1250;
}
.custom-modal-backdrop {
@ -110,7 +112,7 @@ input, textarea {
right: 0;
background-color: rgba(0,0,0,0.3);
padding: 50px;
z-index: 90;
z-index: 1240;
}
.custom-fa {

View File

@ -5,7 +5,7 @@ import { connect } from 'react-redux'
import ActivityCard from './ActivityCard'
import Statistics from './Statistics'
import { getData } from '../../actions'
import { endPagination, getMoreActivities } from '../../actions/activities'
import { getMoreActivities } from '../../actions/activities'
class DashBoard extends React.Component {
constructor(props, context) {
@ -19,14 +19,13 @@ class DashBoard extends React.Component {
this.props.loadActivities()
}
componentWillUnmount() {
this.props.resetPaginationStatus(false)
}
render() {
const {
activities, loadMoreActivities, message, paginationEnd, sports
activities, loadMoreActivities, message, sports
} = this.props
const paginationEnd = activities.length > 0
? activities[activities.length - 1].previous_activity === null
: true
const { page } = this.state
return (
<div>
@ -76,14 +75,10 @@ class DashBoard extends React.Component {
export default connect(
state => ({
activities: state.activities.data,
paginationEnd: state.activities.pagination_end,
message: state.message,
sports: state.sports.data,
}),
dispatch => ({
resetPaginationStatus: () => {
dispatch(endPagination(false))
},
loadActivities: () => {
dispatch(getData('activities', null, 1))
},

View File

@ -5,12 +5,13 @@ import { Link } from 'react-router-dom'
import { apiUrl } from '../../utils'
function NavBar (props) {
function NavBar(props) {
return (
<header>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<span className="navbar-brand">mpwo</span>
<button
<div className="container">
<span className="navbar-brand">mpwo</span>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
@ -18,109 +19,111 @@ function NavBar (props) {
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/',
}}
>
Dashboard
</Link>
</li>
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/activities/add',
}}
>
Add a workout
</Link>
</li>
)}
{props.user.isAdmin && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/admin',
}}
>
Admin
</Link>
</li>
)}
</ul>
<ul className="navbar-nav flex-row ml-md-auto d-none d-md-flex">
{!props.user.isAuthenticated && (
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/register',
pathname: '/',
}}
>
Register
Dashboard
</Link>
</li>
)}
{!props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/login',
}}
>
Login
</Link>
</li>
)}
{props.user.picture === true && (
<img
alt="Avatar"
src={`${apiUrl}users/${props.user.id}/picture` +
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/activities/add',
}}
>
Add a workout
</Link>
</li>
)}
{props.user.isAdmin && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/admin',
}}
>
Admin
</Link>
</li>
)}
</ul>
<ul className="navbar-nav flex-row ml-md-auto d-none d-md-flex">
{!props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/register',
}}
>
Register
</Link>
</li>
)}
{!props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/login',
}}
>
Login
</Link>
</li>
)}
{props.user.picture === true && (
<img
alt="Avatar"
src={`${apiUrl}users/${props.user.id}/picture` +
`?${Date.now()}`}
className="img-fluid App-nav-profile-img"
/>
)}
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/profile',
}}
>
{props.user.username}
</Link>
</li>
)}
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/logout',
}}
>
Logout
</Link>
</li>
)}
</ul>
className="img-fluid App-nav-profile-img"
/>
)}
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/profile',
}}
>
{props.user.username}
</Link>
</li>
)}
{props.user.isAuthenticated && (
<li className="nav-item">
<Link
className="nav-link"
to={{
pathname: '/logout',
}}
>
Logout
</Link>
</li>
)}
</ul>
</div>
</div>
</nav>
</header>
)
}
export default connect(
state => ({
user: state.user,

View File

@ -21,11 +21,6 @@ const handleDataAndError = (state, type, action) => {
const activities = (state = initial.activities, action) => {
switch (action.type) {
case 'END_PAGINATION':
return {
...state,
pagination_end: action.status
}
case 'PUSH_ACTIVITIES':
return {
...state,

View File

@ -40,7 +40,6 @@ export default {
},
activities: {
...emptyData,
pagination_end: false
},
// check if storing gpx content is OK
gpx: null,