Client - display segments - #14
This commit is contained in:
		@@ -81,6 +81,22 @@ export const getActivityGpx = activityId => dispatch => {
 | 
				
			|||||||
  dispatch(setGpx(null))
 | 
					  dispatch(setGpx(null))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getSegmentGpx = (activityId, segmentId) => dispatch => {
 | 
				
			||||||
 | 
					  if (activityId) {
 | 
				
			||||||
 | 
					    return FitTrackeeGenericApi
 | 
				
			||||||
 | 
					    .getData(`activities/${activityId}/gpx/segment/${segmentId}`)
 | 
				
			||||||
 | 
					    .then(ret => {
 | 
				
			||||||
 | 
					      if (ret.status === 'success') {
 | 
				
			||||||
 | 
					         dispatch(setGpx(ret.data.gpx))
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        dispatch(setError(`activities: ${ret.message}`))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(error => dispatch(setError(`activities: ${error}`)))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  dispatch(setGpx(null))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getActivityChartData = activityId => dispatch => {
 | 
					export const getActivityChartData = activityId => dispatch => {
 | 
				
			||||||
  if (activityId) {
 | 
					  if (activityId) {
 | 
				
			||||||
@@ -98,6 +114,22 @@ export const getActivityChartData = activityId => dispatch => {
 | 
				
			|||||||
  dispatch(setChartData(null))
 | 
					  dispatch(setChartData(null))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getSegmentChartData = (activityId, segmentId) => dispatch => {
 | 
				
			||||||
 | 
					  if (activityId) {
 | 
				
			||||||
 | 
					    return FitTrackeeGenericApi
 | 
				
			||||||
 | 
					    .getData(`activities/${activityId}/chart_data/segment/${segmentId}`)
 | 
				
			||||||
 | 
					    .then(ret => {
 | 
				
			||||||
 | 
					      if (ret.status === 'success') {
 | 
				
			||||||
 | 
					         dispatch(setChartData(formatChartData(ret.data.chart_data)))
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        dispatch(setError(`activities: ${ret.message}`))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(error => dispatch(setError(`activities: ${error}`)))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  dispatch(setChartData(null))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const deleteActivity = id => dispatch => FitTrackeeGenericApi
 | 
					export const deleteActivity = id => dispatch => FitTrackeeGenericApi
 | 
				
			||||||
  .deleteData('activities', id)
 | 
					  .deleteData('activities', id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,32 +6,47 @@ import { formatActivityDate } from '../../../utils/activities'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function ActivityCardHeader(props) {
 | 
					export default function ActivityCardHeader(props) {
 | 
				
			||||||
  const { activity, displayModal, sport, title, user } = props
 | 
					  const {
 | 
				
			||||||
 | 
					    activity, dataType, displayModal, segmentId, sport, title, user
 | 
				
			||||||
 | 
					  } = props
 | 
				
			||||||
  const activityDate = activity
 | 
					  const activityDate = activity
 | 
				
			||||||
    ? formatActivityDate(
 | 
					    ? formatActivityDate(
 | 
				
			||||||
        getDateWithTZ(activity.activity_date, user.timezone)
 | 
					        getDateWithTZ(activity.activity_date, user.timezone)
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    : null
 | 
					    : null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const previousUrl = dataType === 'segment' && segmentId !== 0
 | 
				
			||||||
 | 
					    ? `/activities/${activity.id}/segment/${segmentId - 1}`
 | 
				
			||||||
 | 
					    : dataType === 'activity' && activity.previous_activity
 | 
				
			||||||
 | 
					      ? `/activities/${activity.previous_activity}`
 | 
				
			||||||
 | 
					      : null
 | 
				
			||||||
 | 
					    const nextUrl =
 | 
				
			||||||
 | 
					      dataType === 'segment' && segmentId < activity.segments.length - 1
 | 
				
			||||||
 | 
					    ? `/activities/${activity.id}/segment/${segmentId + 1}`
 | 
				
			||||||
 | 
					    : dataType === 'activity' && activity.next_activity
 | 
				
			||||||
 | 
					      ? `/activities/${activity.next_activity}`
 | 
				
			||||||
 | 
					      : null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="container">
 | 
					    <div className="container">
 | 
				
			||||||
      <div className="row">
 | 
					      <div className="row">
 | 
				
			||||||
        <div className="col-auto">
 | 
					        <div className="col-auto">
 | 
				
			||||||
          {activity.previous_activity ? (
 | 
					          {previousUrl ? (
 | 
				
			||||||
            <Link
 | 
					            <Link
 | 
				
			||||||
              className="unlink"
 | 
					              className="unlink"
 | 
				
			||||||
              to={`/activities/${activity.previous_activity}`}
 | 
					              to={previousUrl}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <i
 | 
					              <i
 | 
				
			||||||
                className="fa fa-chevron-left"
 | 
					                className="fa fa-chevron-left"
 | 
				
			||||||
                aria-hidden="true"
 | 
					                aria-hidden="true"
 | 
				
			||||||
                title="See previous activity"
 | 
					                title={`See previous ${dataType}`}
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
            </Link>
 | 
					            </Link>
 | 
				
			||||||
          ) : (
 | 
					          ) : (
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
              className="fa fa-chevron-left inactive-link"
 | 
					              className="fa fa-chevron-left inactive-link"
 | 
				
			||||||
              aria-hidden="true"
 | 
					              aria-hidden="true"
 | 
				
			||||||
              title="No previous activity"
 | 
					              title={`No previous ${dataType}`}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          )}
 | 
					          )}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -43,23 +58,37 @@ export default function ActivityCardHeader(props) {
 | 
				
			|||||||
          />
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className="col">
 | 
					        <div className="col">
 | 
				
			||||||
          {title}{' '}
 | 
					          {dataType === 'activity' ? (
 | 
				
			||||||
          <Link
 | 
					          <>
 | 
				
			||||||
            className="unlink"
 | 
					            {title}{' '}
 | 
				
			||||||
            to={`/activities/${activity.id}/edit`}
 | 
					            <Link
 | 
				
			||||||
          >
 | 
					              className="unlink"
 | 
				
			||||||
 | 
					              to={`/activities/${activity.id}/edit`}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <i
 | 
				
			||||||
 | 
					                className="fa fa-edit custom-fa"
 | 
				
			||||||
 | 
					                aria-hidden="true"
 | 
				
			||||||
 | 
					                title="Edit activity"
 | 
				
			||||||
 | 
					              />
 | 
				
			||||||
 | 
					            </Link>
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
              className="fa fa-edit custom-fa"
 | 
					              className="fa fa-trash custom-fa"
 | 
				
			||||||
              aria-hidden="true"
 | 
					              aria-hidden="true"
 | 
				
			||||||
              title="Edit activity"
 | 
					              onClick={() => displayModal(true)}
 | 
				
			||||||
 | 
					              title="Delete activity"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          </Link>
 | 
					          </>
 | 
				
			||||||
          <i
 | 
					          ) : (
 | 
				
			||||||
            className="fa fa-trash custom-fa"
 | 
					            <>
 | 
				
			||||||
            aria-hidden="true"
 | 
					              <Link
 | 
				
			||||||
            onClick={() => displayModal(true)}
 | 
					                to={`/activities/${activity.id}`}
 | 
				
			||||||
            title="Delete activity"
 | 
					              >
 | 
				
			||||||
          /><br />
 | 
					                {title}
 | 
				
			||||||
 | 
					              </Link>{' '}
 | 
				
			||||||
 | 
					              - segment {segmentId + 1}
 | 
				
			||||||
 | 
					            </>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					          <br />
 | 
				
			||||||
          {activityDate && (
 | 
					          {activityDate && (
 | 
				
			||||||
            <span className="activity-date">
 | 
					            <span className="activity-date">
 | 
				
			||||||
          {`${activityDate.activity_date} - ${activityDate.activity_time}`}
 | 
					          {`${activityDate.activity_date} - ${activityDate.activity_time}`}
 | 
				
			||||||
@@ -67,22 +96,22 @@ export default function ActivityCardHeader(props) {
 | 
				
			|||||||
          )}
 | 
					          )}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className="col-auto">
 | 
					        <div className="col-auto">
 | 
				
			||||||
          {activity.next_activity ? (
 | 
					          {nextUrl ? (
 | 
				
			||||||
            <Link
 | 
					            <Link
 | 
				
			||||||
              className="unlink"
 | 
					              className="unlink"
 | 
				
			||||||
              to={`/activities/${activity.next_activity}`}
 | 
					              to={nextUrl}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <i
 | 
					              <i
 | 
				
			||||||
                className="fa fa-chevron-right"
 | 
					                className="fa fa-chevron-right"
 | 
				
			||||||
                aria-hidden="true"
 | 
					                aria-hidden="true"
 | 
				
			||||||
                title="See next activity"
 | 
					                title={`See next ${dataType}`}
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
            </Link>
 | 
					            </Link>
 | 
				
			||||||
          ) : (
 | 
					          ) : (
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
              className="fa fa-chevron-right inactive-link"
 | 
					              className="fa fa-chevron-right inactive-link"
 | 
				
			||||||
              aria-hidden="true"
 | 
					              aria-hidden="true"
 | 
				
			||||||
              title="No next activity"
 | 
					              title={`No next ${dataType}`}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
          )}
 | 
					          )}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,9 @@ import {
 | 
				
			|||||||
   Area, ComposedChart, Line, ResponsiveContainer, Tooltip, XAxis, YAxis
 | 
					   Area, ComposedChart, Line, ResponsiveContainer, Tooltip, XAxis, YAxis
 | 
				
			||||||
} from 'recharts'
 | 
					} from 'recharts'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { getActivityChartData } from '../../../actions/activities'
 | 
					import {
 | 
				
			||||||
 | 
					  getActivityChartData, getSegmentChartData
 | 
				
			||||||
 | 
					} from '../../../actions/activities'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityCharts extends React.Component {
 | 
					class ActivityCharts extends React.Component {
 | 
				
			||||||
@@ -18,14 +20,24 @@ class ActivityCharts extends React.Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidMount() {
 | 
					  componentDidMount() {
 | 
				
			||||||
    this.props.loadActivityData(this.props.activity.id)
 | 
					    if (this.props.dataType === 'activity') {
 | 
				
			||||||
 | 
					      this.props.loadActivityData(this.props.activity.id)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.props.loadSegmentData(this.props.activity.id, this.props.segmentId)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidUpdate(prevProps) {
 | 
					  componentDidUpdate(prevProps) {
 | 
				
			||||||
    if (prevProps.activity.id !==
 | 
					    if (this.props.dataType === 'activity' && (
 | 
				
			||||||
      this.props.activity.id) {
 | 
					      prevProps.activity.id !== this.props.activity.id)
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        this.props.loadActivityData(this.props.activity.id)
 | 
					        this.props.loadActivityData(this.props.activity.id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.props.dataType === 'segment' && (
 | 
				
			||||||
 | 
					      prevProps.segmentId !== this.props.segmentId)
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					      this.props.loadSegmentData(this.props.activity.id, this.props.segmentId)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentWillUnmount() {
 | 
					  componentWillUnmount() {
 | 
				
			||||||
@@ -196,5 +208,8 @@ export default connect(
 | 
				
			|||||||
    loadActivityData: activityId => {
 | 
					    loadActivityData: activityId => {
 | 
				
			||||||
      dispatch(getActivityChartData(activityId))
 | 
					      dispatch(getActivityChartData(activityId))
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    loadSegmentData: (activityId, segmentId) => {
 | 
				
			||||||
 | 
					      dispatch(getSegmentChartData(activityId, segmentId))
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
)(ActivityCharts)
 | 
					)(ActivityCharts)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,6 @@ import ActivityWeather from './ActivityWeather'
 | 
				
			|||||||
export default function ActivityDetails(props) {
 | 
					export default function ActivityDetails(props) {
 | 
				
			||||||
  const { activity } = props
 | 
					  const { activity } = props
 | 
				
			||||||
  const withPauses = activity.pauses !== '0:00:00' && activity.pauses !== null
 | 
					  const withPauses = activity.pauses !== '0:00:00' && activity.pauses !== null
 | 
				
			||||||
  const recordLDexists = activity.records.find(r => r.record_type === 'LD')
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="activity-details">
 | 
					    <div className="activity-details">
 | 
				
			||||||
      <p>
 | 
					      <p>
 | 
				
			||||||
@@ -14,7 +13,8 @@ export default function ActivityDetails(props) {
 | 
				
			|||||||
          aria-hidden="true"
 | 
					          aria-hidden="true"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        Duration: {activity.moving}
 | 
					        Duration: {activity.moving}
 | 
				
			||||||
        {recordLDexists && (
 | 
					        {activity.records && activity.records.find(r => r.record_type === 'LD'
 | 
				
			||||||
 | 
					        ) && (
 | 
				
			||||||
          <sup>
 | 
					          <sup>
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
              className="fa fa-trophy custom-fa"
 | 
					              className="fa fa-trophy custom-fa"
 | 
				
			||||||
@@ -35,7 +35,7 @@ export default function ActivityDetails(props) {
 | 
				
			|||||||
          aria-hidden="true"
 | 
					          aria-hidden="true"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        Distance: {activity.distance} km
 | 
					        Distance: {activity.distance} km
 | 
				
			||||||
        {activity.records.find(r => r.record_type === 'FD'
 | 
					        {activity.records && activity.records.find(r => r.record_type === 'FD'
 | 
				
			||||||
        ) && (
 | 
					        ) && (
 | 
				
			||||||
          <sup>
 | 
					          <sup>
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
@@ -51,7 +51,7 @@ export default function ActivityDetails(props) {
 | 
				
			|||||||
          aria-hidden="true"
 | 
					          aria-hidden="true"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        Average speed: {activity.ave_speed} km/h
 | 
					        Average speed: {activity.ave_speed} km/h
 | 
				
			||||||
        {activity.records.find(r => r.record_type === 'AS'
 | 
					        {activity.records && activity.records.find(r => r.record_type === 'AS'
 | 
				
			||||||
        ) && (
 | 
					        ) && (
 | 
				
			||||||
          <sup>
 | 
					          <sup>
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
@@ -62,7 +62,7 @@ export default function ActivityDetails(props) {
 | 
				
			|||||||
        )}
 | 
					        )}
 | 
				
			||||||
        <br />
 | 
					        <br />
 | 
				
			||||||
        Max speed : {activity.max_speed} km/h
 | 
					        Max speed : {activity.max_speed} km/h
 | 
				
			||||||
        {activity.records.find(r => r.record_type === 'MS'
 | 
					        {activity.records && activity.records.find(r => r.record_type === 'MS'
 | 
				
			||||||
        ) && (
 | 
					        ) && (
 | 
				
			||||||
          <sup>
 | 
					          <sup>
 | 
				
			||||||
            <i
 | 
					            <i
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@ import React from 'react'
 | 
				
			|||||||
import { GeoJSON, Map, Marker, TileLayer } from 'react-leaflet'
 | 
					import { GeoJSON, Map, Marker, TileLayer } from 'react-leaflet'
 | 
				
			||||||
import { connect } from 'react-redux'
 | 
					import { connect } from 'react-redux'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { getActivityGpx } from '../../../actions/activities'
 | 
					import { getActivityGpx, getSegmentGpx } from '../../../actions/activities'
 | 
				
			||||||
import { thunderforestApiKey } from '../../../utils'
 | 
					import { thunderforestApiKey } from '../../../utils'
 | 
				
			||||||
import { getGeoJson } from '../../../utils/activities'
 | 
					import { getGeoJson } from '../../../utils/activities'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,14 +17,24 @@ class ActivityMap extends React.Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidMount() {
 | 
					  componentDidMount() {
 | 
				
			||||||
    this.props.loadActivityGpx(this.props.activity.id)
 | 
					    if (this.props.dataType === 'activity') {
 | 
				
			||||||
 | 
					      this.props.loadActivityGpx(this.props.activity.id)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.props.loadSegmentGpx(this.props.activity.id, this.props.segmentId)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentDidUpdate(prevProps) {
 | 
					  componentDidUpdate(prevProps) {
 | 
				
			||||||
    if (prevProps.activity.id !==
 | 
					    if (this.props.dataType === 'activity' && (
 | 
				
			||||||
      this.props.activity.id) {
 | 
					      prevProps.activity.id !== this.props.activity.id)
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
        this.props.loadActivityGpx(this.props.activity.id)
 | 
					        this.props.loadActivityGpx(this.props.activity.id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.props.dataType === 'segment' && (
 | 
				
			||||||
 | 
					      prevProps.segmentId !== this.props.segmentId)
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					      this.props.loadSegmentGpx(this.props.activity.id, this.props.segmentId)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  componentWillUnmount() {
 | 
					  componentWillUnmount() {
 | 
				
			||||||
@@ -32,7 +42,9 @@ class ActivityMap extends React.Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  render() {
 | 
					  render() {
 | 
				
			||||||
    const { activity, coordinates, gpxContent } = this.props
 | 
					    const {
 | 
				
			||||||
 | 
					      activity, coordinates, gpxContent
 | 
				
			||||||
 | 
					    } = this.props
 | 
				
			||||||
    const { jsonData } = getGeoJson(gpxContent)
 | 
					    const { jsonData } = getGeoJson(gpxContent)
 | 
				
			||||||
    const bounds = [
 | 
					    const bounds = [
 | 
				
			||||||
      [activity.bounds[0], activity.bounds[1]],
 | 
					      [activity.bounds[0], activity.bounds[1]],
 | 
				
			||||||
@@ -79,5 +91,8 @@ export default connect(
 | 
				
			|||||||
    loadActivityGpx: activityId => {
 | 
					    loadActivityGpx: activityId => {
 | 
				
			||||||
      dispatch(getActivityGpx(activityId))
 | 
					      dispatch(getActivityGpx(activityId))
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    loadSegmentGpx: (activityId, segmentId) => {
 | 
				
			||||||
 | 
					      dispatch(getSegmentGpx(activityId, segmentId))
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
)(ActivityMap)
 | 
					)(ActivityMap)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,11 +3,15 @@ import React from 'react'
 | 
				
			|||||||
export default function ActivityNotes(props) {
 | 
					export default function ActivityNotes(props) {
 | 
				
			||||||
  const { notes } = props
 | 
					  const { notes } = props
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="card">
 | 
					    <div className="row">
 | 
				
			||||||
      <div className="card-body">
 | 
					      <div className="col">
 | 
				
			||||||
        Notes
 | 
					        <div className="card activity-card">
 | 
				
			||||||
        <div className="activity-notes">
 | 
					          <div className="card-body">
 | 
				
			||||||
          {notes ? notes : 'No notes'}
 | 
					            Notes
 | 
				
			||||||
 | 
					            <div className="activity-notes">
 | 
				
			||||||
 | 
					              {notes ? notes : 'No notes'}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					import React from 'react'
 | 
				
			||||||
 | 
					import { Link } from 'react-router-dom'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function ActivitySegments(props) {
 | 
				
			||||||
 | 
					  const { segments } = props
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className="row">
 | 
				
			||||||
 | 
					      <div className="col">
 | 
				
			||||||
 | 
					        <div className="card activity-card">
 | 
				
			||||||
 | 
					          <div className="card-body">
 | 
				
			||||||
 | 
					            Segments
 | 
				
			||||||
 | 
					            <div className="activity-segments">
 | 
				
			||||||
 | 
					              <ul>
 | 
				
			||||||
 | 
					                {segments.map((segment, index) => (
 | 
				
			||||||
 | 
					                  // eslint-disable-next-line react/no-array-index-key
 | 
				
			||||||
 | 
					                  <li key={`segment-${index}`}>
 | 
				
			||||||
 | 
					                    <Link
 | 
				
			||||||
 | 
					                      to={`/activities/${
 | 
				
			||||||
 | 
					                        segment.activity_id}/segment/${index}`}
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
 | 
					                      segment {index + 1}
 | 
				
			||||||
 | 
					                    </Link>{' '}
 | 
				
			||||||
 | 
					                    ({segment.distance} km, duration: {segment.duration})
 | 
				
			||||||
 | 
					                  </li>
 | 
				
			||||||
 | 
					                ))}
 | 
				
			||||||
 | 
					              </ul>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,6 +8,7 @@ import ActivityDetails from './ActivityDetails'
 | 
				
			|||||||
import ActivityMap from './ActivityMap'
 | 
					import ActivityMap from './ActivityMap'
 | 
				
			||||||
import ActivityNoMap from './ActivityNoMap'
 | 
					import ActivityNoMap from './ActivityNoMap'
 | 
				
			||||||
import ActivityNotes from './ActivityNotes'
 | 
					import ActivityNotes from './ActivityNotes'
 | 
				
			||||||
 | 
					import ActivitySegments from './ActivitySegments'
 | 
				
			||||||
import CustomModal from '../../Common/CustomModal'
 | 
					import CustomModal from '../../Common/CustomModal'
 | 
				
			||||||
import { getOrUpdateData } from '../../../actions'
 | 
					import { getOrUpdateData } from '../../../actions'
 | 
				
			||||||
import { deleteActivity } from '../../../actions/activities'
 | 
					import { deleteActivity } from '../../../actions/activities'
 | 
				
			||||||
@@ -66,7 +67,10 @@ class ActivityDisplay extends React.Component {
 | 
				
			|||||||
    const [sport] = activity
 | 
					    const [sport] = activity
 | 
				
			||||||
      ? sports.filter(s => s.id === activity.sport_id)
 | 
					      ? sports.filter(s => s.id === activity.sport_id)
 | 
				
			||||||
      : []
 | 
					      : []
 | 
				
			||||||
 | 
					    const segmentId = parseInt(this.props.match.params.segmentId)
 | 
				
			||||||
 | 
					    const dataType = segmentId >= 0
 | 
				
			||||||
 | 
					      ? 'segment'
 | 
				
			||||||
 | 
					      : 'activity'
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div className="activity-page">
 | 
					      <div className="activity-page">
 | 
				
			||||||
        <Helmet>
 | 
					        <Helmet>
 | 
				
			||||||
@@ -94,6 +98,8 @@ class ActivityDisplay extends React.Component {
 | 
				
			|||||||
                      <div className="card-header">
 | 
					                      <div className="card-header">
 | 
				
			||||||
                        <ActivityCardHeader
 | 
					                        <ActivityCardHeader
 | 
				
			||||||
                          activity={activity}
 | 
					                          activity={activity}
 | 
				
			||||||
 | 
					                          dataType={dataType}
 | 
				
			||||||
 | 
					                          segmentId={segmentId}
 | 
				
			||||||
                          sport={sport}
 | 
					                          sport={sport}
 | 
				
			||||||
                          title={title}
 | 
					                          title={title}
 | 
				
			||||||
                          user={user}
 | 
					                          user={user}
 | 
				
			||||||
@@ -107,13 +113,19 @@ class ActivityDisplay extends React.Component {
 | 
				
			|||||||
                              <ActivityMap
 | 
					                              <ActivityMap
 | 
				
			||||||
                                activity={activity}
 | 
					                                activity={activity}
 | 
				
			||||||
                                coordinates={coordinates}
 | 
					                                coordinates={coordinates}
 | 
				
			||||||
 | 
					                                dataType={dataType}
 | 
				
			||||||
 | 
					                                segmentId={segmentId}
 | 
				
			||||||
                              />
 | 
					                              />
 | 
				
			||||||
                            ) : (
 | 
					                            ) : (
 | 
				
			||||||
                              <ActivityNoMap />
 | 
					                              <ActivityNoMap />
 | 
				
			||||||
                            )}
 | 
					                            )}
 | 
				
			||||||
                          </div>
 | 
					                          </div>
 | 
				
			||||||
                          <div className="col">
 | 
					                          <div className="col">
 | 
				
			||||||
                            <ActivityDetails activity={activity} />
 | 
					                            <ActivityDetails
 | 
				
			||||||
 | 
					                              activity={dataType === 'activity'
 | 
				
			||||||
 | 
					                                ? activity
 | 
				
			||||||
 | 
					                                : activity.segments[segmentId]}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
                          </div>
 | 
					                          </div>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
@@ -130,6 +142,8 @@ class ActivityDisplay extends React.Component {
 | 
				
			|||||||
                              <div className="chart-title">Chart</div>
 | 
					                              <div className="chart-title">Chart</div>
 | 
				
			||||||
                              <ActivityCharts
 | 
					                              <ActivityCharts
 | 
				
			||||||
                                activity={activity}
 | 
					                                activity={activity}
 | 
				
			||||||
 | 
					                                dataType={dataType}
 | 
				
			||||||
 | 
					                                segmentId={segmentId}
 | 
				
			||||||
                                updateCoordinates={
 | 
					                                updateCoordinates={
 | 
				
			||||||
                                  e => this.updateCoordinates(e)
 | 
					                                  e => this.updateCoordinates(e)
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
@@ -141,7 +155,14 @@ class ActivityDisplay extends React.Component {
 | 
				
			|||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                )}
 | 
					                )}
 | 
				
			||||||
                <ActivityNotes notes={activity.notes} />
 | 
					                {dataType === 'activity' && (
 | 
				
			||||||
 | 
					                  <>
 | 
				
			||||||
 | 
					                    <ActivityNotes notes={activity.notes} />
 | 
				
			||||||
 | 
					                    {activity.segments.length > 1 && (
 | 
				
			||||||
 | 
					                      <ActivitySegments segments={activity.segments} />
 | 
				
			||||||
 | 
					                    )}
 | 
				
			||||||
 | 
					                  </>
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,10 @@ function Activity () {
 | 
				
			|||||||
            exact path="/activities/:activityId/edit"
 | 
					            exact path="/activities/:activityId/edit"
 | 
				
			||||||
            component={ActivityEdit}
 | 
					            component={ActivityEdit}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
 | 
					          <Route
 | 
				
			||||||
 | 
					            path="/activities/:activityId/segment/:segmentId"
 | 
				
			||||||
 | 
					            component={ActivityDisplay}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
          <Route component={NotFound} />
 | 
					          <Route component={NotFound} />
 | 
				
			||||||
        </Switch>
 | 
					        </Switch>
 | 
				
			||||||
      ) : (<Redirect to="/login" />)}
 | 
					      ) : (<Redirect to="/login" />)}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,7 +102,7 @@ label {
 | 
				
			|||||||
  line-height: 400px;
 | 
					  line-height: 400px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.activity-notes {
 | 
					.activity-notes, .actvitiy-segments {
 | 
				
			||||||
  font-size: 0.9em;
 | 
					  font-size: 0.9em;
 | 
				
			||||||
  font-style: italic;
 | 
					  font-style: italic;
 | 
				
			||||||
  margin-top: 10px;
 | 
					  margin-top: 10px;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user