Client: display user statistics - #9
This commit is contained in:
parent
a079a4a741
commit
7ac1109e1e
@ -5,6 +5,7 @@ import mpwoApi from '../mwpoApi/activities'
|
|||||||
import { history } from '../index'
|
import { history } from '../index'
|
||||||
import { formatChartData } from '../utils'
|
import { formatChartData } from '../utils'
|
||||||
import { setError, setLoading } from './index'
|
import { setError, setLoading } from './index'
|
||||||
|
import { loadProfile } from './user'
|
||||||
|
|
||||||
export const pushActivities = activities => ({
|
export const pushActivities = activities => ({
|
||||||
type: 'PUSH_ACTIVITIES',
|
type: 'PUSH_ACTIVITIES',
|
||||||
@ -33,8 +34,10 @@ export const addActivity = form => dispatch => mpwoApi
|
|||||||
if (ret.data.activities.length === 0) {
|
if (ret.data.activities.length === 0) {
|
||||||
dispatch(setError('activities: no correct file'))
|
dispatch(setError('activities: no correct file'))
|
||||||
} else if (ret.data.activities.length === 1) {
|
} else if (ret.data.activities.length === 1) {
|
||||||
|
dispatch(loadProfile())
|
||||||
history.push(`/activities/${ret.data.activities[0].id}`)
|
history.push(`/activities/${ret.data.activities[0].id}`)
|
||||||
} else { // ret.data.activities.length > 1
|
} else { // ret.data.activities.length > 1
|
||||||
|
dispatch(loadProfile())
|
||||||
history.push('/')
|
history.push('/')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -49,6 +52,7 @@ export const addActivityWithoutGpx = form => dispatch => mpwoApi
|
|||||||
.addActivityWithoutGpx(form)
|
.addActivityWithoutGpx(form)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (ret.status === 'created') {
|
if (ret.status === 'created') {
|
||||||
|
dispatch(loadProfile())
|
||||||
history.push(`/activities/${ret.data.activities[0].id}`)
|
history.push(`/activities/${ret.data.activities[0].id}`)
|
||||||
} else {
|
} else {
|
||||||
dispatch(setError(`activities: ${ret.message}`))
|
dispatch(setError(`activities: ${ret.message}`))
|
||||||
@ -95,6 +99,7 @@ export const deleteActivity = id => dispatch => mpwoGenericApi
|
|||||||
.deleteData('activities', id)
|
.deleteData('activities', id)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (ret.status === 204) {
|
if (ret.status === 204) {
|
||||||
|
dispatch(loadProfile())
|
||||||
history.push('/')
|
history.push('/')
|
||||||
} else {
|
} else {
|
||||||
dispatch(setError(`activities: ${ret.status}`))
|
dispatch(setError(`activities: ${ret.status}`))
|
||||||
@ -107,6 +112,7 @@ export const editActivity = form => dispatch => mpwoGenericApi
|
|||||||
.updateData('activities', form)
|
.updateData('activities', form)
|
||||||
.then(ret => {
|
.then(ret => {
|
||||||
if (ret.status === 'success') {
|
if (ret.status === 'success') {
|
||||||
|
dispatch(loadProfile())
|
||||||
history.push(`/activities/${ret.data.activities[0].id}`)
|
history.push(`/activities/${ret.data.activities[0].id}`)
|
||||||
} else {
|
} else {
|
||||||
dispatch(setError(`activities: ${ret.message}`))
|
dispatch(setError(`activities: ${ret.message}`))
|
||||||
|
@ -94,6 +94,10 @@ input, textarea {
|
|||||||
color: goldenrod;
|
color: goldenrod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fa-color {
|
||||||
|
color: #405976;
|
||||||
|
}
|
||||||
|
|
||||||
.leaflet-container {
|
.leaflet-container {
|
||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
@ -161,6 +165,10 @@ input, textarea {
|
|||||||
max-height: 35px;
|
max-height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.huge {
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
.inactive-link {
|
.inactive-link {
|
||||||
color: lightgrey;
|
color: lightgrey;
|
||||||
}
|
}
|
||||||
|
64
mpwo_client/src/components/Dashboard/UserStatistics.jsx
Normal file
64
mpwo_client/src/components/Dashboard/UserStatistics.jsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
|
||||||
|
export default function UserStatistics (props) {
|
||||||
|
const { user } = props
|
||||||
|
return (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col">
|
||||||
|
<div className="card activity-card">
|
||||||
|
<div className="card-body row">
|
||||||
|
<div className="col-3">
|
||||||
|
<i className="fa fa-calendar fa-3x fa-color" />
|
||||||
|
</div>
|
||||||
|
<div className="col-9 text-right">
|
||||||
|
<div className="huge">{user.nbActivities}</div>
|
||||||
|
<div>{user.nbActivities === 1 ? 'activity' : 'activities'}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<div className="card activity-card">
|
||||||
|
<div className="card-body row">
|
||||||
|
<div className="col-3">
|
||||||
|
<i className="fa fa-road fa-3x fa-color" />
|
||||||
|
</div>
|
||||||
|
<div className="col-9 text-right">
|
||||||
|
<div className="huge">
|
||||||
|
{Math.round(user.totalDistance * 100) / 100}
|
||||||
|
</div>
|
||||||
|
<div>km</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<div className="card activity-card">
|
||||||
|
<div className="card-body row">
|
||||||
|
<div className="col-3">
|
||||||
|
<i className="fa fa-clock-o fa-3x fa-color" />
|
||||||
|
</div>
|
||||||
|
<div className="col-9 text-right">
|
||||||
|
<div className="huge">{user.totalDuration}</div>
|
||||||
|
<div>total duration</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
<div className="card activity-card">
|
||||||
|
<div className="card-body row">
|
||||||
|
<div className="col-3">
|
||||||
|
<i className="fa fa-tags fa-3x fa-color" />
|
||||||
|
</div>
|
||||||
|
<div className="col-9 text-right">
|
||||||
|
<div className="huge">{user.nbSports}</div>
|
||||||
|
<div>{`sport${user.nbSports === 1 ? '' : 's'}`}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
@ -6,6 +6,7 @@ import ActivityCard from './ActivityCard'
|
|||||||
import Calendar from './../Others/Calendar'
|
import Calendar from './../Others/Calendar'
|
||||||
import Records from './Records'
|
import Records from './Records'
|
||||||
import Statistics from './Statistics'
|
import Statistics from './Statistics'
|
||||||
|
import UserStatistics from './UserStatistics'
|
||||||
import { getData } from '../../actions'
|
import { getData } from '../../actions'
|
||||||
import { getMoreActivities } from '../../actions/activities'
|
import { getMoreActivities } from '../../actions/activities'
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ class DashBoard extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
activities, loadMoreActivities, message, records, sports
|
activities, loadMoreActivities, message, records, sports, user
|
||||||
} = this.props
|
} = this.props
|
||||||
const paginationEnd = activities.length > 0
|
const paginationEnd = activities.length > 0
|
||||||
? activities[activities.length - 1].previous_activity === null
|
? activities[activities.length - 1].previous_activity === null
|
||||||
@ -39,6 +40,7 @@ class DashBoard extends React.Component {
|
|||||||
) : (
|
) : (
|
||||||
(activities && sports.length > 0) && (
|
(activities && sports.length > 0) && (
|
||||||
<div className="container dashboard">
|
<div className="container dashboard">
|
||||||
|
<UserStatistics user={user} />
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
<Records records={records} sports={sports} />
|
<Records records={records} sports={sports} />
|
||||||
@ -83,6 +85,7 @@ export default connect(
|
|||||||
message: state.message,
|
message: state.message,
|
||||||
records: state.records.data,
|
records: state.records.data,
|
||||||
sports: state.sports.data,
|
sports: state.sports.data,
|
||||||
|
user: state.user,
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
loadActivities: () => {
|
loadActivities: () => {
|
||||||
|
@ -185,6 +185,10 @@ const user = (state = initial.user, action) => {
|
|||||||
picture: action.message.data.picture === true
|
picture: action.message.data.picture === true
|
||||||
? action.message.data.picture
|
? action.message.data.picture
|
||||||
: false,
|
: false,
|
||||||
|
nbActivities: action.message.data.nb_activities,
|
||||||
|
nbSports: action.message.data.nb_sports,
|
||||||
|
totalDistance: action.message.data.total_distance,
|
||||||
|
totalDuration: action.message.data.total_duration,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return state
|
return state
|
||||||
|
Loading…
Reference in New Issue
Block a user