Client: activities navigation
This commit is contained in:
parent
f744eb0769
commit
948e49beef
@ -21,6 +21,13 @@ class ActivityDisplay extends React.Component {
|
|||||||
this.props.loadActivity(this.props.match.params.activityId)
|
this.props.loadActivity(this.props.match.params.activityId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (prevProps.match.params.activityId !==
|
||||||
|
this.props.match.params.activityId) {
|
||||||
|
this.props.loadActivity(this.props.match.params.activityId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { activities, message, onDeleteActivity, sports } = this.props
|
const { activities, message, onDeleteActivity, sports } = this.props
|
||||||
const { displayModal } = this.state
|
const { displayModal } = this.state
|
||||||
@ -41,7 +48,7 @@ class ActivityDisplay extends React.Component {
|
|||||||
<code>{message}</code>
|
<code>{message}</code>
|
||||||
) : (
|
) : (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
{ displayModal &&
|
{displayModal &&
|
||||||
<CustomModal
|
<CustomModal
|
||||||
title="Confirmation"
|
title="Confirmation"
|
||||||
text="Are you sure you want to delete this activity?"
|
text="Are you sure you want to delete this activity?"
|
||||||
@ -51,134 +58,176 @@ class ActivityDisplay extends React.Component {
|
|||||||
}}
|
}}
|
||||||
close={() => this.setState({ displayModal: false })}
|
close={() => this.setState({ displayModal: false })}
|
||||||
/>}
|
/>}
|
||||||
{activity && sport && activities.length === 1 && (
|
{activity && sport && activities.length === 1 && (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-auto col-activity-logo">
|
<div className="col-auto">
|
||||||
<img
|
{activity.previous_activity ? (
|
||||||
className="sport-img-medium"
|
<Link
|
||||||
src={sport.img}
|
className="unlink"
|
||||||
alt="sport logo"
|
to={`/activities/${activity.previous_activity}`}
|
||||||
/>
|
>
|
||||||
</div>
|
<i
|
||||||
<div className="col">
|
className="fa fa-chevron-left"
|
||||||
{title}{' '}
|
aria-hidden="true"
|
||||||
<Link
|
/>
|
||||||
className="unlink"
|
</Link>
|
||||||
to={`/activities/${activity.id}/edit`}
|
) : (
|
||||||
>
|
<i
|
||||||
<i
|
className="fa fa-chevron-left inactive-link"
|
||||||
className="fa fa-edit custom-fa"
|
aria-hidden="true"
|
||||||
aria-hidden="true"
|
/>
|
||||||
/>
|
)}
|
||||||
</Link>
|
</div>
|
||||||
<i
|
<div className="col-auto col-activity-logo">
|
||||||
className="fa fa-trash custom-fa"
|
<img
|
||||||
aria-hidden="true"
|
className="sport-img-medium"
|
||||||
onClick={() => this.setState({ displayModal: true })}
|
src={sport.img}
|
||||||
/><br />
|
alt="sport logo"
|
||||||
{activityDate && (
|
/>
|
||||||
<span className="activity-date">
|
</div>
|
||||||
|
<div className="col">
|
||||||
|
{title}{' '}
|
||||||
|
<Link
|
||||||
|
className="unlink"
|
||||||
|
to={`/activities/${activity.id}/edit`}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-edit custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<i
|
||||||
|
className="fa fa-trash custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
onClick={
|
||||||
|
() => this.setState({ displayModal: true })
|
||||||
|
}
|
||||||
|
/><br />
|
||||||
|
{activityDate && (
|
||||||
|
<span className="activity-date">
|
||||||
{`${activityDate.activity_date} - ${
|
{`${activityDate.activity_date} - ${
|
||||||
activityDate.activity_time}`}
|
activityDate.activity_time}`}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="col-auto">
|
||||||
|
{activity.next_activity ? (
|
||||||
|
<Link
|
||||||
|
className="unlink"
|
||||||
|
to={`/activities/${activity.next_activity}`}
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-chevron-right"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<i
|
||||||
|
className="fa fa-chevron-right inactive-link"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="card-body">
|
||||||
<div className="card-body">
|
<div className="row">
|
||||||
<div className="row">
|
{activity.with_gpx && (
|
||||||
{activity.with_gpx && (
|
<div className="col-8">
|
||||||
<div className="col-8">
|
<ActivityMap activity={activity} />
|
||||||
<ActivityMap activity={activity} />
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="col">
|
||||||
|
<p>
|
||||||
|
<i
|
||||||
|
className="fa fa-clock-o custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
Duration: {activity.duration}
|
||||||
|
{activity.records.find(r => r.record_type === 'LD'
|
||||||
|
) && (
|
||||||
|
<sup>
|
||||||
|
<i
|
||||||
|
className="fa fa-trophy custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</sup>
|
||||||
|
)} {' '}
|
||||||
|
{activity.pauses !== '0:00:00' &&
|
||||||
|
activity.pauses !== null && (
|
||||||
|
`(pauses: ${activity.pauses})`
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i
|
||||||
|
className="fa fa-road custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
Distance: {activity.distance} km
|
||||||
|
{activity.records.find(r => r.record_type === 'FD'
|
||||||
|
) && (
|
||||||
|
<sup>
|
||||||
|
<i
|
||||||
|
className="fa fa-trophy custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</sup>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<i
|
||||||
|
className="fa fa-tachometer custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
Average speed: {activity.ave_speed} km/h
|
||||||
|
{activity.records.find(r => r.record_type === 'AS'
|
||||||
|
) && (
|
||||||
|
<sup>
|
||||||
|
<i
|
||||||
|
className="fa fa-trophy custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</sup>
|
||||||
|
)}
|
||||||
|
<br />
|
||||||
|
Max speed : {activity.max_speed} km/h
|
||||||
|
{activity.records.find(r => r.record_type === 'MS'
|
||||||
|
) && (
|
||||||
|
<sup>
|
||||||
|
<i
|
||||||
|
className="fa fa-trophy custom-fa"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</sup>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
{activity.min_alt && activity.max_alt && (
|
||||||
|
<p>
|
||||||
|
<i className="fi-mountains custom-fa" />
|
||||||
|
Min altitude: {activity.min_alt}m
|
||||||
|
<br />
|
||||||
|
Max altitude: {activity.max_alt}m
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{activity.ascent && activity.descent && (
|
||||||
|
<p>
|
||||||
|
<i className="fa fa-location-arrow custom-fa" />
|
||||||
|
Ascent: {activity.ascent}m
|
||||||
|
<br />
|
||||||
|
Descent: {activity.descent}m
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
<div className="col">
|
|
||||||
<p>
|
|
||||||
<i
|
|
||||||
className="fa fa-clock-o custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
Duration: {activity.duration}
|
|
||||||
{activity.records.find(r => r.record_type === 'LD') && (
|
|
||||||
<sup>
|
|
||||||
<i
|
|
||||||
className="fa fa-trophy custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</sup>
|
|
||||||
)} {' '}
|
|
||||||
{activity.pauses !== '0:00:00' &&
|
|
||||||
activity.pauses !== null && (
|
|
||||||
`(pauses: ${activity.pauses})`
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<i
|
|
||||||
className="fa fa-road custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
Distance: {activity.distance} km
|
|
||||||
{activity.records.find(r => r.record_type === 'FD') && (
|
|
||||||
<sup>
|
|
||||||
<i
|
|
||||||
className="fa fa-trophy custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</sup>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<i
|
|
||||||
className="fa fa-tachometer custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
Average speed: {activity.ave_speed} km/h
|
|
||||||
{activity.records.find(r => r.record_type === 'AS') && (
|
|
||||||
<sup>
|
|
||||||
<i
|
|
||||||
className="fa fa-trophy custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</sup>
|
|
||||||
)}
|
|
||||||
<br />
|
|
||||||
Max speed : {activity.max_speed} km/h
|
|
||||||
{activity.records.find(r => r.record_type === 'MS') && (
|
|
||||||
<sup>
|
|
||||||
<i
|
|
||||||
className="fa fa-trophy custom-fa"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</sup>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
{activity.min_alt && activity.max_alt && (
|
|
||||||
<p>
|
|
||||||
<i className="fi-mountains custom-fa" />
|
|
||||||
Min altitude: {activity.min_alt}m
|
|
||||||
<br />
|
|
||||||
Max altitude: {activity.max_alt}m
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{activity.ascent && activity.descent && (
|
|
||||||
<p>
|
|
||||||
<i className="fa fa-location-arrow custom-fa" />
|
|
||||||
Ascent: {activity.ascent}m
|
|
||||||
<br />
|
|
||||||
Descent: {activity.descent}m
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import hash from 'object-hash'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { GeoJSON, Map, TileLayer } from 'react-leaflet'
|
import { GeoJSON, Map, TileLayer } from 'react-leaflet'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
@ -18,6 +19,13 @@ class ActivityMap extends React.Component {
|
|||||||
this.props.loadActivityGpx(this.props.activity.id)
|
this.props.loadActivityGpx(this.props.activity.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (prevProps.activity.id !==
|
||||||
|
this.props.activity.id) {
|
||||||
|
this.props.loadActivityGpx(this.props.activity.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.props.loadActivityGpx(null)
|
this.props.loadActivityGpx(null)
|
||||||
}
|
}
|
||||||
@ -44,7 +52,11 @@ class ActivityMap extends React.Component {
|
|||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
url={`https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=${thunderforestApiKey}`}
|
url={`https://{s}.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=${thunderforestApiKey}`}
|
||||||
/>
|
/>
|
||||||
<GeoJSON data={jsonData} />
|
<GeoJSON
|
||||||
|
// hash as a key to force re-rendering
|
||||||
|
key={hash(jsonData)}
|
||||||
|
data={jsonData}
|
||||||
|
/>
|
||||||
</Map>
|
</Map>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -124,6 +124,10 @@ input, textarea {
|
|||||||
max-height: 35px;
|
max-height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inactive-link {
|
||||||
|
color: lightgrey;
|
||||||
|
}
|
||||||
|
|
||||||
.sport-img-medium {
|
.sport-img-medium {
|
||||||
max-width: 45px;
|
max-width: 45px;
|
||||||
max-height: 45px;
|
max-height: 45px;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"date-fns": "^1.29.0",
|
"date-fns": "^1.29.0",
|
||||||
"history": "^4.7.2",
|
"history": "^4.7.2",
|
||||||
"leaflet": "^1.3.1",
|
"leaflet": "^1.3.1",
|
||||||
|
"object-hash": "^1.3.0",
|
||||||
"react": "^16.3.2",
|
"react": "^16.3.2",
|
||||||
"react-dom": "^16.3.2",
|
"react-dom": "^16.3.2",
|
||||||
"react-helmet": "^5.2.0",
|
"react-helmet": "^5.2.0",
|
||||||
|
@ -6146,7 +6146,7 @@ object-copy@^0.1.0:
|
|||||||
define-property "^0.2.5"
|
define-property "^0.2.5"
|
||||||
kind-of "^3.0.3"
|
kind-of "^3.0.3"
|
||||||
|
|
||||||
object-hash@^1.1.4:
|
object-hash@^1.1.4, object-hash@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"
|
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.0.tgz#76d9ba6ff113cf8efc0d996102851fe6723963e2"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user