diff --git a/mpwo_api/mpwo_api/activities/stats.py b/mpwo_api/mpwo_api/activities/stats.py
index 928bffeb..484c3145 100644
--- a/mpwo_api/mpwo_api/activities/stats.py
+++ b/mpwo_api/mpwo_api/activities/stats.py
@@ -70,14 +70,12 @@ def get_activities(user_id, type):
activity_date = activity.activity_date - timedelta(
days=activity.activity_date.isoweekday()
)
- time_period = datetime.strftime(activity_date,
- "%Y-%m-%d_W%U")
+ time_period = datetime.strftime(activity_date, "%Y-%m-%d")
elif time == 'weekm': # week start Monday
activity_date = activity.activity_date - timedelta(
days=activity.activity_date.weekday()
)
- time_period = datetime.strftime(activity_date,
- "%Y-%m-%d_W%W")
+ time_period = datetime.strftime(activity_date, "%Y-%m-%d")
elif time == 'month':
time_period = datetime.strftime(activity.activity_date, "%Y-%m") # noqa
elif time == 'year' or not time:
diff --git a/mpwo_api/mpwo_api/tests/test_stats_api.py b/mpwo_api/mpwo_api/tests/test_stats_api.py
index da435ebc..23795863 100644
--- a/mpwo_api/mpwo_api/tests/test_stats_api.py
+++ b/mpwo_api/mpwo_api/tests/test_stats_api.py
@@ -468,7 +468,7 @@ def test_get_stats_by_week_all_activities(
assert 'success' in data['status']
assert data['data']['statistics'] == \
{
- '2017-03-19_W12':
+ '2017-03-19':
{
'1':
{
@@ -477,7 +477,7 @@ def test_get_stats_by_week_all_activities(
'total_duration': 1024
}
},
- '2017-05-28_W22':
+ '2017-05-28':
{
'1':
{
@@ -486,7 +486,7 @@ def test_get_stats_by_week_all_activities(
'total_duration': 3456
}
},
- '2017-12-31_W53':
+ '2017-12-31':
{
'1':
{
@@ -495,7 +495,7 @@ def test_get_stats_by_week_all_activities(
'total_duration': 1024
}
},
- '2018-02-18_W07':
+ '2018-02-18':
{
'1':
{
@@ -504,7 +504,7 @@ def test_get_stats_by_week_all_activities(
'total_duration': 1600
}
},
- '2018-03-25_W12':
+ '2018-03-25':
{
'1':
{
@@ -519,7 +519,7 @@ def test_get_stats_by_week_all_activities(
'total_duration': 6000
}
},
- '2018-05-06_W18':
+ '2018-05-06':
{
'1':
{
@@ -558,7 +558,7 @@ def test_get_stats_by_week_all_activities_week_13(
assert 'success' in data['status']
assert data['data']['statistics'] == \
{
- '2018-03-25_W12':
+ '2018-03-25':
{
'1':
{
@@ -603,7 +603,7 @@ def test_get_stats_by_weekm_all_activities(
assert 'success' in data['status']
assert data['data']['statistics'] == \
{
- '2017-03-20_W12':
+ '2017-03-20':
{
'1':
{
@@ -612,7 +612,7 @@ def test_get_stats_by_weekm_all_activities(
'total_duration': 1024
}
},
- '2017-05-29_W22':
+ '2017-05-29':
{
'1':
{
@@ -621,7 +621,7 @@ def test_get_stats_by_weekm_all_activities(
'total_duration': 3456
}
},
- '2018-01-01_W01':
+ '2018-01-01':
{
'1':
{
@@ -630,7 +630,7 @@ def test_get_stats_by_weekm_all_activities(
'total_duration': 1024
}
},
- '2018-02-19_W08':
+ '2018-02-19':
{
'1':
{
@@ -639,7 +639,7 @@ def test_get_stats_by_weekm_all_activities(
'total_duration': 1600
}
},
- '2018-03-26_W13':
+ '2018-03-26':
{
'1':
{
@@ -654,7 +654,7 @@ def test_get_stats_by_weekm_all_activities(
'total_duration': 6000
}
},
- '2018-05-07_W19':
+ '2018-05-07':
{
'1':
{
@@ -693,7 +693,7 @@ def test_get_stats_by_weekm_all_activities_week_13(
assert 'success' in data['status']
assert data['data']['statistics'] == \
{
- '2018-03-26_W13':
+ '2018-03-26':
{
'1':
{
diff --git a/mpwo_client/src/actions/stats.js b/mpwo_client/src/actions/stats.js
new file mode 100644
index 00000000..3562eea9
--- /dev/null
+++ b/mpwo_client/src/actions/stats.js
@@ -0,0 +1,13 @@
+import mpwoApi from '../mwpoApi/stats'
+import { setData, setError } from './index'
+
+export const getStats = (userId, type, data) => dispatch => mpwoApi
+ .getStats(userId, type, data)
+ .then(ret => {
+ if (ret.status === 'success') {
+ dispatch(setData('statistics', ret.data))
+ } else {
+ dispatch(setError(`statistics: ${ret.message}`))
+ }
+ })
+ .catch(error => dispatch(setError(`statistics: ${error}`)))
diff --git a/mpwo_client/src/components/App.css b/mpwo_client/src/components/App.css
index 36ce15a3..3f72fc1b 100644
--- a/mpwo_client/src/components/App.css
+++ b/mpwo_client/src/components/App.css
@@ -115,6 +115,10 @@ input, textarea {
font-style: italic;
}
+.chart-month {
+ font-size: 0.8em;
+}
+
.chart-radio {
display: flex;
font-size: 0.8em;
diff --git a/mpwo_client/src/components/Dashboard/Statistics.jsx b/mpwo_client/src/components/Dashboard/Statistics.jsx
index 6e9ce731..ea7f67bf 100644
--- a/mpwo_client/src/components/Dashboard/Statistics.jsx
+++ b/mpwo_client/src/components/Dashboard/Statistics.jsx
@@ -1,15 +1,132 @@
+import { endOfMonth, format, startOfMonth } from 'date-fns'
import React from 'react'
+import { connect } from 'react-redux'
+import {
+ Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis
+} from 'recharts'
+
+import { getStats } from '../../actions/stats'
+import { formatStats } from '../../utils'
-export default function ActivityCard () {
- return (
-
-
- Statistics
+class Statistics extends React.Component {
+ constructor(props, context) {
+ super(props, context)
+ const date = new Date()
+ this.state = {
+ start: startOfMonth(date),
+ end: endOfMonth(date),
+ displayedData: 'distance'
+ }
+ }
+
+ componentDidMount() {
+ this.props.loadMonthActivities(
+ this.props.user.id,
+ this.state.start,
+ this.state.end,
+ )
+ }
+
+ handleRadioChange (changeEvent) {
+ this.setState({
+ displayedData: changeEvent.target.name
+ })
+ }
+
+
+ render() {
+ const { sports, statistics } = this.props
+ const { displayedData, end, start } = this.state
+ const data = []
+ const stats = formatStats(statistics, sports, start, end)
+ const colors = [
+ '#55a8a3',
+ '#98C3A9',
+ '#D0838A',
+ '#ECC77E',
+ '#926692',
+ '#929292'
+ ]
+ return (
+
+
+ This month
+
+
+ {data === [] ? (
+ 'No activities'
+ ) : (
+
+ )}
+
-
- coming soon...
-
-
- )
+ )
+ }
}
+
+export default connect(
+ state => ({
+ sports: state.sports.data,
+ statistics: state.statistics.data,
+ user: state.user,
+ }),
+ dispatch => ({
+ loadMonthActivities: (userId, start, end) => {
+ const dateFormat = 'YYYY-MM-DD'
+ const params = {
+ start: format(start, dateFormat),
+ end: format(end, dateFormat),
+ time: 'week'
+ }
+ dispatch(getStats(userId, 'by_time', params))
+ },
+ })
+)(Statistics)
diff --git a/mpwo_client/src/components/Dashboard/index.jsx b/mpwo_client/src/components/Dashboard/index.jsx
index ab7e882d..8da14004 100644
--- a/mpwo_client/src/components/Dashboard/index.jsx
+++ b/mpwo_client/src/components/Dashboard/index.jsx
@@ -43,8 +43,8 @@ class DashBoard extends React.Component {
-
+
diff --git a/mpwo_client/src/mwpoApi/index.js b/mpwo_client/src/mwpoApi/index.js
index f4b42e82..f8227caf 100644
--- a/mpwo_client/src/mwpoApi/index.js
+++ b/mpwo_client/src/mwpoApi/index.js
@@ -10,15 +10,15 @@ export default class MpwoApi {
} else if (Object.keys(data).length > 0) {
url = `${url}?${
data.page ? `&page=${data.page}` : ''
- }${
+ }${
data.start ? `&from=${data.start}` : ''
- }${
+ }${
data.end ? `&to=${data.end}` : ''
- }${
+ }${
data.order ? `&order=${data.order}` : ''
- }${
+ }${
data.per_page ? `&per_page=${data.per_page}` : ''
- }`
+ }`
}
const params = {
url: url,
diff --git a/mpwo_client/src/mwpoApi/stats.js b/mpwo_client/src/mwpoApi/stats.js
new file mode 100644
index 00000000..276459d4
--- /dev/null
+++ b/mpwo_client/src/mwpoApi/stats.js
@@ -0,0 +1,25 @@
+import { apiUrl, createRequest } from '../utils'
+
+export default class MpwoApi {
+
+ static getStats(userID, type, data = {}) {
+ let url = `${apiUrl}stats/${userID}/${type}`
+ if (Object.keys(data).length > 0) {
+ url = `${url}?${
+ data.start ? `&from=${data.start}` : ''
+ }${
+ data.end ? `&to=${data.end}` : ''
+ }${
+ data.time ? `&time=${data.time}` : ''
+ }${
+ data.sport_id ? `&sport_id=${data.sport_id}` : ''
+ }`
+ }
+ const params = {
+ url: url,
+ method: 'GET',
+ }
+ return createRequest(params)
+ }
+
+}
diff --git a/mpwo_client/src/reducers/index.js b/mpwo_client/src/reducers/index.js
index 6a574d5a..bb94822d 100644
--- a/mpwo_client/src/reducers/index.js
+++ b/mpwo_client/src/reducers/index.js
@@ -195,6 +195,9 @@ const user = (state = initial.user, action) => {
}
}
+const statistics = (state = initial.statistics, action) =>
+ handleDataAndError(state, 'statistics', action)
+
const reducers = combineReducers({
activities,
calendarActivities,
@@ -208,6 +211,7 @@ const reducers = combineReducers({
records,
router: routerReducer,
sports,
+ statistics,
user,
})
diff --git a/mpwo_client/src/reducers/initial.js b/mpwo_client/src/reducers/initial.js
index b1771c4d..f0fb1b05 100644
--- a/mpwo_client/src/reducers/initial.js
+++ b/mpwo_client/src/reducers/initial.js
@@ -53,5 +53,8 @@ export default {
},
sports: {
...emptyData,
- }
+ },
+ statistics: {
+ data: {},
+ },
}
diff --git a/mpwo_client/src/utils.js b/mpwo_client/src/utils.js
index a0d363c2..70753a97 100644
--- a/mpwo_client/src/utils.js
+++ b/mpwo_client/src/utils.js
@@ -1,5 +1,5 @@
import togeojson from '@mapbox/togeojson'
-import { format, parse, subHours } from 'date-fns'
+import { addDays, format, parse, startOfWeek, subHours } from 'date-fns'
export const apiUrl = `${process.env.REACT_APP_API_URL}/api/`
export const thunderforestApiKey = `${
@@ -106,3 +106,38 @@ export const formatChartData = chartData => {
}
return chartData
}
+
+export const formatStats = (stats, sports, startDate, endDate) => {
+ const nbActivitiesStats = []
+ const distanceStats = []
+ const durationStats = []
+
+ for (let day = startOfWeek(startDate);
+ day <= endDate;
+ day = addDays(day, 7)
+ ) {
+ const date = format(day, 'YYYY-MM-DD')
+ const dataNbActivities = { date }
+ const dataDistance = { date }
+ const dataDuration = { date }
+
+ if (stats[date]) {
+ Object.keys(stats[date]).map(sportId => {
+ const sportLabel = sports.filter(s => s.id === +sportId)[0].label
+ dataNbActivities[sportLabel] = stats[date][sportId].nb_activities
+ dataDistance[sportLabel] = stats[date][sportId].total_distance
+ dataDuration[sportLabel] = stats[date][sportId].total_duration
+ return null
+ })
+ }
+ nbActivitiesStats.push(dataNbActivities)
+ distanceStats.push(dataDistance)
+ durationStats.push(dataDuration)
+ }
+
+ return {
+ activities: nbActivitiesStats,
+ distance: distanceStats,
+ duration: durationStats
+ }
+}