diff --git a/fittrackee_client/src/components/Activities/ActivitiesList.jsx b/fittrackee_client/src/components/Activities/ActivitiesList.jsx index 7369bb42..9bfb0ddc 100644 --- a/fittrackee_client/src/components/Activities/ActivitiesList.jsx +++ b/fittrackee_client/src/components/Activities/ActivitiesList.jsx @@ -2,8 +2,10 @@ import { format } from 'date-fns' import React from 'react' import { Link } from 'react-router-dom' +import { getDateWithTZ } from '../../utils' + export default function ActivitiesList (props) { - const { activities, sports } = props + const { activities, sports, user } = props return (
@@ -36,7 +38,12 @@ export default function ActivitiesList (props) { {activity.title} - {format(activity.activity_date, 'DD/MM/YYYY HH:mm')} + + {format( + getDateWithTZ(activity.activity_date, user.timezone), + 'DD/MM/YYYY HH:mm' + )} + {Number(activity.distance).toFixed(2)} km diff --git a/fittrackee_client/src/components/Activities/index.jsx b/fittrackee_client/src/components/Activities/index.jsx index 17ab5ac4..72cdd394 100644 --- a/fittrackee_client/src/components/Activities/index.jsx +++ b/fittrackee_client/src/components/Activities/index.jsx @@ -36,7 +36,7 @@ class Activities extends React.Component { } render() { const { - activities, loadActivities, loadMoreActivities, message, sports + activities, loadActivities, loadMoreActivities, message, sports, user } = this.props const { params } = this.state const paginationEnd = activities.length > 0 @@ -63,6 +63,7 @@ class Activities extends React.Component { {!paginationEnd && ({ loadActivities: params => { diff --git a/fittrackee_client/src/components/Activity/ActivityDisplay/ActivityCardHeader.jsx b/fittrackee_client/src/components/Activity/ActivityDisplay/ActivityCardHeader.jsx index 3c85cd74..915f1591 100644 --- a/fittrackee_client/src/components/Activity/ActivityDisplay/ActivityCardHeader.jsx +++ b/fittrackee_client/src/components/Activity/ActivityDisplay/ActivityCardHeader.jsx @@ -1,13 +1,15 @@ import React from 'react' import { Link } from 'react-router-dom' -import { formatActivityDate } from '../../../utils' +import { formatActivityDate, getDateWithTZ } from '../../../utils' export default function ActivityCardHeader(props) { - const { activity, displayModal, sport, title } = props + const { activity, displayModal, sport, title, user } = props const activityDate = activity - ? formatActivityDate(activity.activity_date) + ? formatActivityDate( + getDateWithTZ(activity.activity_date, user.timezone) + ) : null return (
diff --git a/fittrackee_client/src/components/Activity/ActivityDisplay/index.jsx b/fittrackee_client/src/components/Activity/ActivityDisplay/index.jsx index 7d67d25d..76de4b5c 100644 --- a/fittrackee_client/src/components/Activity/ActivityDisplay/index.jsx +++ b/fittrackee_client/src/components/Activity/ActivityDisplay/index.jsx @@ -34,7 +34,7 @@ class ActivityDisplay extends React.Component { } render() { - const { activities, message, onDeleteActivity, sports } = this.props + const { activities, message, onDeleteActivity, sports, user } = this.props const { displayModal } = this.state const [activity] = activities const title = activity ? activity.title : 'Activity' @@ -71,6 +71,7 @@ class ActivityDisplay extends React.Component { activity={activity} sport={sport} title={title} + user={user} displayModal={() => this.displayModal(true)} />
diff --git a/fittrackee_client/src/components/Dashboard/ActivityCard.jsx b/fittrackee_client/src/components/Dashboard/ActivityCard.jsx index 887c9180..597c6889 100644 --- a/fittrackee_client/src/components/Dashboard/ActivityCard.jsx +++ b/fittrackee_client/src/components/Dashboard/ActivityCard.jsx @@ -2,10 +2,10 @@ import { format } from 'date-fns' import React from 'react' import { Link } from 'react-router-dom' -import { apiUrl } from '../../utils' +import { apiUrl, getDateWithTZ } from '../../utils' export default function ActivityCard (props) { - const { activity, sports } = props + const { activity, sports, user } = props return (
@@ -13,7 +13,10 @@ export default function ActivityCard (props) { {sports.filter(sport => sport.id === activity.sport_id) .map(sport => sport.label)} -{' '} - {format(activity.activity_date, 'DD/MM/YYYY HH:mm')} + {format( + getDateWithTZ(activity.activity_date, user.timezone), + 'DD/MM/YYYY HH:mm' + )}
diff --git a/fittrackee_client/src/components/Dashboard/Records.jsx b/fittrackee_client/src/components/Dashboard/Records.jsx index c4acb2eb..b9c91a52 100644 --- a/fittrackee_client/src/components/Dashboard/Records.jsx +++ b/fittrackee_client/src/components/Dashboard/Records.jsx @@ -4,7 +4,7 @@ import { Link } from 'react-router-dom' import { formatRecord } from '../../utils' export default function RecordsCard (props) { - const { records, sports } = props + const { records, sports, user } = props const recordsBySport = records.reduce((sportList, record) => { const sport = sports.find(s => s.id === record.sport_id) if (sportList[sport.label] === void 0) { @@ -13,7 +13,7 @@ export default function RecordsCard (props) { records: [], } } - sportList[sport.label].records.push(formatRecord(record)) + sportList[sport.label].records.push(formatRecord(record, user.timezone)) return sportList }, {}) diff --git a/fittrackee_client/src/components/Dashboard/index.jsx b/fittrackee_client/src/components/Dashboard/index.jsx index aba60195..38633347 100644 --- a/fittrackee_client/src/components/Dashboard/index.jsx +++ b/fittrackee_client/src/components/Dashboard/index.jsx @@ -45,7 +45,7 @@ class DashBoard extends React.Component {
- +
@@ -55,6 +55,7 @@ class DashBoard extends React.Component { activity={activity} key={activity.id} sports={sports} + user={user} />) )) : (
diff --git a/fittrackee_client/src/components/Others/Calendar.jsx b/fittrackee_client/src/components/Others/Calendar.jsx index 8ba79eff..ff67462d 100644 --- a/fittrackee_client/src/components/Others/Calendar.jsx +++ b/fittrackee_client/src/components/Others/Calendar.jsx @@ -6,6 +6,7 @@ import { connect } from 'react-redux' import { Link } from 'react-router-dom' import { getMonthActivities } from '../../actions/activities' +import { getDateWithTZ } from '../../utils' const getStartAndEndMonth = date => { const monthStart = dateFns.startOfMonth(date) @@ -73,10 +74,13 @@ class Calendar extends React.Component { } filterActivities(day) { - const { activities } = this.props + const { activities, user } = this.props if (activities) { return activities - .filter(act => dateFns.isSameDay(act.activity_date, day)) + .filter(act => dateFns.isSameDay( + getDateWithTZ(act.activity_date, user.timezone), + day + )) } return [] } @@ -108,11 +112,12 @@ class Calendar extends React.Component { {dayActivities.map(act => ( activity sport logo s.id === act.sport_id) .map(s => s.img)} - alt="activity sport logo" + title={act.title} /> ))} @@ -167,6 +172,7 @@ export default connect( state => ({ activities: state.calendarActivities.data, sports: state.sports.data, + user: state.user, }), dispatch => ({ loadMonthActivities: (start, end) => { diff --git a/fittrackee_client/src/utils.js b/fittrackee_client/src/utils.js index 93156ded..4f0979db 100644 --- a/fittrackee_client/src/utils.js +++ b/fittrackee_client/src/utils.js @@ -1,5 +1,6 @@ import togeojson from '@mapbox/togeojson' import { addDays, format, parse, startOfWeek, subHours } from 'date-fns' +import { DateTime } from 'luxon' export const apiUrl = `${process.env.REACT_APP_API_URL}/api/` export const thunderforestApiKey = `${ @@ -63,24 +64,33 @@ export const getGeoJson = gpxContent => { return { jsonData } } -export const formatActivityDate = (activityDateTime, dateFormat = null) => { - if (activityDateTime) { - const dateTime = parse(activityDateTime) - return { - activity_date: format( - dateTime, - dateFormat ? dateFormat : 'DD/MM/YYYY' - ), - activity_time: activityDateTime.match(/[0-2][0-9]:[0-5][0-9]/)[0] - } + +export const getDateWithTZ = (date, tz) => { + if (!date) { + return '' + } + const dt = DateTime.fromISO(format(date)).setZone(tz) + return parse(dt.toFormat('yyyy-MM-dd HH:mm:ss')) +} + +export const formatActivityDate = ( + dateTime, + dateFormat = null, + timeFormat = null, +) => { + if (!dateFormat) { + dateFormat = 'DD/MM/YYYY' + } + if (!timeFormat) { + timeFormat = 'HH:mm' } return { - activity_date: null, - activity_time: null, + activity_date: dateTime ? format(dateTime, dateFormat) : null, + activity_time: dateTime ? format(dateTime, timeFormat) : null, } } -export const formatRecord = record => { +export const formatRecord = (record, tz) => { let value, recordType = null switch (record.record_type) { case 'AS': @@ -97,7 +107,9 @@ export const formatRecord = record => { recordType = 'Longest duration' } return { - activity_date: formatActivityDate(record.activity_date).activity_date, + activity_date: formatActivityDate( + getDateWithTZ(record.activity_date, tz) + ).activity_date, activity_id: record.activity_id, id: record.id, record_type: recordType, diff --git a/package.json b/package.json index f1831459..67ce881f 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "date-fns": "^1.29.0", "history": "^4.7.2", "leaflet": "^1.3.1", + "luxon": "^1.2.1", "object-hash": "^1.3.0", "react": "^16.4.0", "react-dom": "^16.4.0", diff --git a/yarn.lock b/yarn.lock index 123fe36f..25863d1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5669,6 +5669,10 @@ lru-cache@^3.2.0: dependencies: pseudomap "^1.0.1" +luxon@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.2.1.tgz#5c4948d141939c2b2820f0c3a99276932245efb1" + macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"