Client - application translation
This commit is contained in:
		@@ -11,6 +11,7 @@ export default function ActivityCardHeader(props) {
 | 
			
		||||
    displayModal,
 | 
			
		||||
    segmentId,
 | 
			
		||||
    sport,
 | 
			
		||||
    t,
 | 
			
		||||
    title,
 | 
			
		||||
    user,
 | 
			
		||||
  } = props
 | 
			
		||||
@@ -40,14 +41,14 @@ export default function ActivityCardHeader(props) {
 | 
			
		||||
              <i
 | 
			
		||||
                className="fa fa-chevron-left"
 | 
			
		||||
                aria-hidden="true"
 | 
			
		||||
                title={`See previous ${dataType}`}
 | 
			
		||||
                title={t(`activities:See previous ${dataType}`)}
 | 
			
		||||
              />
 | 
			
		||||
            </Link>
 | 
			
		||||
          ) : (
 | 
			
		||||
            <i
 | 
			
		||||
              className="fa fa-chevron-left inactive-link"
 | 
			
		||||
              aria-hidden="true"
 | 
			
		||||
              title={`No previous ${dataType}`}
 | 
			
		||||
              title={t(`activities:No previous ${dataType}`)}
 | 
			
		||||
            />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
@@ -62,14 +63,14 @@ export default function ActivityCardHeader(props) {
 | 
			
		||||
                <i
 | 
			
		||||
                  className="fa fa-edit custom-fa"
 | 
			
		||||
                  aria-hidden="true"
 | 
			
		||||
                  title="Edit activity"
 | 
			
		||||
                  title={t('activities:Edit activity')}
 | 
			
		||||
                />
 | 
			
		||||
              </Link>
 | 
			
		||||
              <i
 | 
			
		||||
                className="fa fa-trash custom-fa"
 | 
			
		||||
                aria-hidden="true"
 | 
			
		||||
                onClick={() => displayModal(true)}
 | 
			
		||||
                title="Delete activity"
 | 
			
		||||
                title={t('activities:Delete activity')}
 | 
			
		||||
              />
 | 
			
		||||
            </>
 | 
			
		||||
          ) : (
 | 
			
		||||
@@ -80,7 +81,7 @@ export default function ActivityCardHeader(props) {
 | 
			
		||||
              >
 | 
			
		||||
                {title}
 | 
			
		||||
              </Link>{' '}
 | 
			
		||||
              - segment {segmentId}
 | 
			
		||||
              - {t('activities:segment')} {segmentId}
 | 
			
		||||
            </>
 | 
			
		||||
          )}
 | 
			
		||||
          <br />
 | 
			
		||||
@@ -96,14 +97,14 @@ export default function ActivityCardHeader(props) {
 | 
			
		||||
              <i
 | 
			
		||||
                className="fa fa-chevron-right"
 | 
			
		||||
                aria-hidden="true"
 | 
			
		||||
                title={`See next ${dataType}`}
 | 
			
		||||
                title={t(`activities:See next ${dataType}`)}
 | 
			
		||||
              />
 | 
			
		||||
            </Link>
 | 
			
		||||
          ) : (
 | 
			
		||||
            <i
 | 
			
		||||
              className="fa fa-chevron-right inactive-link"
 | 
			
		||||
              aria-hidden="true"
 | 
			
		||||
              title={`No next ${dataType}`}
 | 
			
		||||
              title={t(`activities:No next ${dataType}`)}
 | 
			
		||||
            />
 | 
			
		||||
          )}
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { chartData, updateCoordinates } = this.props
 | 
			
		||||
    const { chartData, t, updateCoordinates } = this.props
 | 
			
		||||
    const { displayDistance } = this.state
 | 
			
		||||
    const xInterval = chartData ? parseInt(chartData.length / 10, 10) : 0
 | 
			
		||||
    let xDataKey, xScale
 | 
			
		||||
@@ -102,7 +102,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  checked={displayDistance}
 | 
			
		||||
                  onChange={e => this.handleRadioChange(e)}
 | 
			
		||||
                />
 | 
			
		||||
                distance
 | 
			
		||||
                {t('activities:distance')}
 | 
			
		||||
              </label>
 | 
			
		||||
              <label className="radioLabel col-md-1">
 | 
			
		||||
                <input
 | 
			
		||||
@@ -111,7 +111,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  checked={!displayDistance}
 | 
			
		||||
                  onChange={e => this.handleRadioChange(e)}
 | 
			
		||||
                />
 | 
			
		||||
                duration
 | 
			
		||||
                {t('activities:duration')}
 | 
			
		||||
              </label>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="row chart-radio">
 | 
			
		||||
@@ -123,7 +123,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  checked={this.displayData('speed')}
 | 
			
		||||
                  onChange={e => this.handleLegendChange(e)}
 | 
			
		||||
                />
 | 
			
		||||
                speed
 | 
			
		||||
                {t('activities:speed')}
 | 
			
		||||
              </label>
 | 
			
		||||
              <label className="radioLabel col-md-1">
 | 
			
		||||
                <input
 | 
			
		||||
@@ -132,7 +132,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  checked={this.displayData('elevation')}
 | 
			
		||||
                  onChange={e => this.handleLegendChange(e)}
 | 
			
		||||
                />
 | 
			
		||||
                elevation
 | 
			
		||||
                {t('activities:elevation')}
 | 
			
		||||
              </label>
 | 
			
		||||
              <div className="col-md-5" />
 | 
			
		||||
            </div>
 | 
			
		||||
@@ -147,7 +147,11 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  <XAxis
 | 
			
		||||
                    allowDecimals={false}
 | 
			
		||||
                    dataKey={xDataKey}
 | 
			
		||||
                    label={{ value: xDataKey, offset: 0, position: 'bottom' }}
 | 
			
		||||
                    label={{
 | 
			
		||||
                      value: t(`activities:${xDataKey}`),
 | 
			
		||||
                      offset: 0,
 | 
			
		||||
                      position: 'bottom',
 | 
			
		||||
                    }}
 | 
			
		||||
                    scale={xScale}
 | 
			
		||||
                    interval={xInterval}
 | 
			
		||||
                    tickFormatter={value =>
 | 
			
		||||
@@ -157,7 +161,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  />
 | 
			
		||||
                  <YAxis
 | 
			
		||||
                    label={{
 | 
			
		||||
                      value: 'speed (km/h)',
 | 
			
		||||
                      value: `${t('activities:speed')} (km/h)`,
 | 
			
		||||
                      angle: -90,
 | 
			
		||||
                      position: 'left',
 | 
			
		||||
                    }}
 | 
			
		||||
@@ -165,7 +169,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  />
 | 
			
		||||
                  <YAxis
 | 
			
		||||
                    label={{
 | 
			
		||||
                      value: 'altitude (m)',
 | 
			
		||||
                      value: `${t('activities:elevation')} (m)`,
 | 
			
		||||
                      angle: -90,
 | 
			
		||||
                      position: 'right',
 | 
			
		||||
                    }}
 | 
			
		||||
@@ -177,6 +181,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                      yAxisId="right"
 | 
			
		||||
                      type="linear"
 | 
			
		||||
                      dataKey="elevation"
 | 
			
		||||
                      name={t('activities:elevation')}
 | 
			
		||||
                      fill="#e5e5e5"
 | 
			
		||||
                      stroke="#cccccc"
 | 
			
		||||
                      dot={false}
 | 
			
		||||
@@ -188,6 +193,7 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                      yAxisId="left"
 | 
			
		||||
                      type="linear"
 | 
			
		||||
                      dataKey="speed"
 | 
			
		||||
                      name={t('activities:speed')}
 | 
			
		||||
                      stroke="#8884d8"
 | 
			
		||||
                      strokeWidth={2}
 | 
			
		||||
                      dot={false}
 | 
			
		||||
@@ -197,19 +203,22 @@ class ActivityCharts extends React.Component {
 | 
			
		||||
                  <Tooltip
 | 
			
		||||
                    labelFormatter={value =>
 | 
			
		||||
                      displayDistance
 | 
			
		||||
                        ? `distance: ${value} km`
 | 
			
		||||
                        : `duration: ${format(value, 'HH:mm:ss')}`
 | 
			
		||||
                        ? `${t('activities:distance')}: ${value} km`
 | 
			
		||||
                        : `${t('activities:duration')}: ${format(
 | 
			
		||||
                            value,
 | 
			
		||||
                            'HH:mm:ss'
 | 
			
		||||
                          )}`
 | 
			
		||||
                    }
 | 
			
		||||
                  />
 | 
			
		||||
                </ComposedChart>
 | 
			
		||||
              </ResponsiveContainer>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="chart-info">
 | 
			
		||||
              data from gpx, without any cleaning
 | 
			
		||||
              {t('activities:data from gpx, without any cleaning')}
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        ) : (
 | 
			
		||||
          'No data to display'
 | 
			
		||||
          t('activities:No data to display')
 | 
			
		||||
        )}
 | 
			
		||||
      </div>
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
@@ -3,13 +3,13 @@ import React from 'react'
 | 
			
		||||
import ActivityWeather from './ActivityWeather'
 | 
			
		||||
 | 
			
		||||
export default function ActivityDetails(props) {
 | 
			
		||||
  const { activity } = props
 | 
			
		||||
  const { activity, t } = props
 | 
			
		||||
  const withPauses = activity.pauses !== '0:00:00' && activity.pauses !== null
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="activity-details">
 | 
			
		||||
      <p>
 | 
			
		||||
        <i className="fa fa-clock-o custom-fa" aria-hidden="true" />
 | 
			
		||||
        Duration: {activity.moving}
 | 
			
		||||
        {t('activities:Duration')}: {activity.moving}
 | 
			
		||||
        {activity.records &&
 | 
			
		||||
          activity.records.find(r => r.record_type === 'LD') && (
 | 
			
		||||
            <sup>
 | 
			
		||||
@@ -18,14 +18,14 @@ export default function ActivityDetails(props) {
 | 
			
		||||
          )}
 | 
			
		||||
        {withPauses && (
 | 
			
		||||
          <span>
 | 
			
		||||
            <br />
 | 
			
		||||
            (pauses: {activity.pauses}, total duration: {activity.duration})
 | 
			
		||||
            <br />({t('activities:pauses')}: {activity.pauses},{' '}
 | 
			
		||||
            {t('activities:total duration')}: {activity.duration})
 | 
			
		||||
          </span>
 | 
			
		||||
        )}
 | 
			
		||||
      </p>
 | 
			
		||||
      <p>
 | 
			
		||||
        <i className="fa fa-road custom-fa" aria-hidden="true" />
 | 
			
		||||
        Distance: {activity.distance} km
 | 
			
		||||
        {t('activities:Distance')}: {activity.distance} km
 | 
			
		||||
        {activity.records &&
 | 
			
		||||
          activity.records.find(r => r.record_type === 'FD') && (
 | 
			
		||||
            <sup>
 | 
			
		||||
@@ -35,7 +35,7 @@ export default function ActivityDetails(props) {
 | 
			
		||||
      </p>
 | 
			
		||||
      <p>
 | 
			
		||||
        <i className="fa fa-tachometer custom-fa" aria-hidden="true" />
 | 
			
		||||
        Average speed: {activity.ave_speed} km/h
 | 
			
		||||
        {t('activities:Average speed')}: {activity.ave_speed} km/h
 | 
			
		||||
        {activity.records &&
 | 
			
		||||
          activity.records.find(r => r.record_type === 'AS') && (
 | 
			
		||||
            <sup>
 | 
			
		||||
@@ -43,7 +43,7 @@ export default function ActivityDetails(props) {
 | 
			
		||||
            </sup>
 | 
			
		||||
          )}
 | 
			
		||||
        <br />
 | 
			
		||||
        Max speed : {activity.max_speed} km/h
 | 
			
		||||
        {t('activities:Max. speed')}: {activity.max_speed} km/h
 | 
			
		||||
        {activity.records &&
 | 
			
		||||
          activity.records.find(r => r.record_type === 'MS') && (
 | 
			
		||||
            <sup>
 | 
			
		||||
@@ -54,20 +54,20 @@ export default function ActivityDetails(props) {
 | 
			
		||||
      {activity.min_alt && activity.max_alt && (
 | 
			
		||||
        <p>
 | 
			
		||||
          <i className="fi-mountains custom-fa" />
 | 
			
		||||
          Min altitude: {activity.min_alt}m
 | 
			
		||||
          {t('activities:Min. altitude')}: {activity.min_alt}m
 | 
			
		||||
          <br />
 | 
			
		||||
          Max altitude: {activity.max_alt}m
 | 
			
		||||
          {t('activities:Max. altitude')}: {activity.max_alt}m
 | 
			
		||||
        </p>
 | 
			
		||||
      )}
 | 
			
		||||
      {activity.ascent && activity.descent && (
 | 
			
		||||
        <p>
 | 
			
		||||
          <i className="fa fa-location-arrow custom-fa" />
 | 
			
		||||
          Ascent: {activity.ascent}m
 | 
			
		||||
          {t('activities:Ascent')}: {activity.ascent}m
 | 
			
		||||
          <br />
 | 
			
		||||
          Descent: {activity.descent}m
 | 
			
		||||
          {t('activities:Descent')}: {activity.descent}m
 | 
			
		||||
        </p>
 | 
			
		||||
      )}
 | 
			
		||||
      <ActivityWeather activity={activity} />
 | 
			
		||||
      <ActivityWeather activity={activity} t={t} />
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,8 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
 | 
			
		||||
export default function ActivityNoMap() {
 | 
			
		||||
  return <div className="activity-no-map text-center">No Map</div>
 | 
			
		||||
export default function ActivityNoMap(props) {
 | 
			
		||||
  const { t } = props
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="activity-no-map text-center">{t('activities:No Map')}</div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
 | 
			
		||||
export default function ActivityNotes(props) {
 | 
			
		||||
  const { notes } = props
 | 
			
		||||
  const { notes, t } = props
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="row">
 | 
			
		||||
      <div className="col">
 | 
			
		||||
        <div className="card activity-card">
 | 
			
		||||
          <div className="card-body">
 | 
			
		||||
            Notes
 | 
			
		||||
            <div className="activity-notes">{notes ? notes : 'No notes'}</div>
 | 
			
		||||
            <div className="activity-notes">
 | 
			
		||||
              {notes ? notes : t('activities:No notes')}
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,13 @@ import React from 'react'
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
 | 
			
		||||
export default function ActivitySegments(props) {
 | 
			
		||||
  const { segments } = props
 | 
			
		||||
  const { segments, t } = props
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="row">
 | 
			
		||||
      <div className="col">
 | 
			
		||||
        <div className="card activity-card">
 | 
			
		||||
          <div className="card-body">
 | 
			
		||||
            Segments
 | 
			
		||||
            {t('activities:Segments')}
 | 
			
		||||
            <div className="activity-segments">
 | 
			
		||||
              <ul>
 | 
			
		||||
                {segments.map((segment, index) => (
 | 
			
		||||
@@ -21,9 +21,10 @@ export default function ActivitySegments(props) {
 | 
			
		||||
                      to={`/activities/${segment.activity_id}/segment/${index +
 | 
			
		||||
                        1}`}
 | 
			
		||||
                    >
 | 
			
		||||
                      segment {index + 1}
 | 
			
		||||
                      {t('activities:segment')} {index + 1}
 | 
			
		||||
                    </Link>{' '}
 | 
			
		||||
                    ({segment.distance} km, duration: {segment.duration})
 | 
			
		||||
                    ({t('activities:distance')}: {segment.distance} km,{' '}
 | 
			
		||||
                    {t('activities:duration')}: {segment.duration})
 | 
			
		||||
                  </li>
 | 
			
		||||
                ))}
 | 
			
		||||
              </ul>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
 | 
			
		||||
export default function ActivityWeather(props) {
 | 
			
		||||
  const { activity } = props
 | 
			
		||||
  const { activity, t } = props
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="container">
 | 
			
		||||
      {activity.weather_start && activity.weather_end && (
 | 
			
		||||
@@ -10,7 +10,7 @@ export default function ActivityWeather(props) {
 | 
			
		||||
            <tr>
 | 
			
		||||
              <th />
 | 
			
		||||
              <th>
 | 
			
		||||
                Start
 | 
			
		||||
                {t('activities:Start')}
 | 
			
		||||
                <br />
 | 
			
		||||
                <img
 | 
			
		||||
                  className="weather-img"
 | 
			
		||||
@@ -20,7 +20,7 @@ export default function ActivityWeather(props) {
 | 
			
		||||
                />
 | 
			
		||||
              </th>
 | 
			
		||||
              <th>
 | 
			
		||||
                End
 | 
			
		||||
                {t('activities:End')}
 | 
			
		||||
                <br />
 | 
			
		||||
                <img
 | 
			
		||||
                  className="weather-img"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
import { Helmet } from 'react-helmet'
 | 
			
		||||
import { withTranslation } from 'react-i18next'
 | 
			
		||||
import { connect } from 'react-redux'
 | 
			
		||||
 | 
			
		||||
import ActivityCardHeader from './ActivityCardHeader'
 | 
			
		||||
@@ -62,7 +63,14 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { activities, message, onDeleteActivity, sports, user } = this.props
 | 
			
		||||
    const {
 | 
			
		||||
      activities,
 | 
			
		||||
      message,
 | 
			
		||||
      onDeleteActivity,
 | 
			
		||||
      sports,
 | 
			
		||||
      t,
 | 
			
		||||
      user,
 | 
			
		||||
    } = this.props
 | 
			
		||||
    const { coordinates, displayModal } = this.state
 | 
			
		||||
    const [activity] = activities
 | 
			
		||||
    const title = activity ? activity.title : 'Activity'
 | 
			
		||||
@@ -82,8 +90,10 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
          <div className="container">
 | 
			
		||||
            {displayModal && (
 | 
			
		||||
              <CustomModal
 | 
			
		||||
                title="Confirmation"
 | 
			
		||||
                text="Are you sure you want to delete this activity?"
 | 
			
		||||
                title={t('activities:Confirmation')}
 | 
			
		||||
                text={t(
 | 
			
		||||
                  'activities:Are you sure you want to delete this activity?'
 | 
			
		||||
                )}
 | 
			
		||||
                confirm={() => {
 | 
			
		||||
                  onDeleteActivity(activity.id)
 | 
			
		||||
                  this.displayModal(false)
 | 
			
		||||
@@ -102,6 +112,7 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
                          dataType={dataType}
 | 
			
		||||
                          segmentId={segmentId}
 | 
			
		||||
                          sport={sport}
 | 
			
		||||
                          t={t}
 | 
			
		||||
                          title={title}
 | 
			
		||||
                          user={user}
 | 
			
		||||
                          displayModal={() => this.displayModal(true)}
 | 
			
		||||
@@ -118,7 +129,7 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
                                segmentId={segmentId}
 | 
			
		||||
                              />
 | 
			
		||||
                            ) : (
 | 
			
		||||
                              <ActivityNoMap />
 | 
			
		||||
                              <ActivityNoMap t={t} />
 | 
			
		||||
                            )}
 | 
			
		||||
                          </div>
 | 
			
		||||
                          <div className="col">
 | 
			
		||||
@@ -128,6 +139,7 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
                                  ? activity
 | 
			
		||||
                                  : activity.segments[segmentId - 1]
 | 
			
		||||
                              }
 | 
			
		||||
                              t={t}
 | 
			
		||||
                            />
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
@@ -147,6 +159,7 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
                                activity={activity}
 | 
			
		||||
                                dataType={dataType}
 | 
			
		||||
                                segmentId={segmentId}
 | 
			
		||||
                                t={t}
 | 
			
		||||
                                updateCoordinates={e =>
 | 
			
		||||
                                  this.updateCoordinates(e)
 | 
			
		||||
                                }
 | 
			
		||||
@@ -160,9 +173,9 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
                )}
 | 
			
		||||
                {dataType === 'activity' && (
 | 
			
		||||
                  <>
 | 
			
		||||
                    <ActivityNotes notes={activity.notes} />
 | 
			
		||||
                    <ActivityNotes notes={activity.notes} t={t} />
 | 
			
		||||
                    {activity.segments.length > 1 && (
 | 
			
		||||
                      <ActivitySegments segments={activity.segments} />
 | 
			
		||||
                      <ActivitySegments segments={activity.segments} t={t} />
 | 
			
		||||
                    )}
 | 
			
		||||
                  </>
 | 
			
		||||
                )}
 | 
			
		||||
@@ -175,7 +188,8 @@ class ActivityDisplay extends React.Component {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect(
 | 
			
		||||
export default withTranslation()(
 | 
			
		||||
  connect(
 | 
			
		||||
    state => ({
 | 
			
		||||
      activities: state.activities.data,
 | 
			
		||||
      message: state.message,
 | 
			
		||||
@@ -190,4 +204,5 @@ export default connect(
 | 
			
		||||
        dispatch(deleteActivity(activityId))
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
)(ActivityDisplay)
 | 
			
		||||
  )(ActivityDisplay)
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
import { useTranslation } from 'react-i18next'
 | 
			
		||||
 | 
			
		||||
export default function CustomModal(props) {
 | 
			
		||||
  const { t } = useTranslation()
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="custom-modal-backdrop">
 | 
			
		||||
      <div className="custom-modal">
 | 
			
		||||
@@ -11,7 +13,7 @@ export default function CustomModal(props) {
 | 
			
		||||
              type="button"
 | 
			
		||||
              className="close"
 | 
			
		||||
              aria-label="Close"
 | 
			
		||||
              onClick={() => props.close}
 | 
			
		||||
              onClick={() => props.close()}
 | 
			
		||||
            >
 | 
			
		||||
              <span aria-hidden="true">×</span>
 | 
			
		||||
            </button>
 | 
			
		||||
@@ -25,14 +27,14 @@ export default function CustomModal(props) {
 | 
			
		||||
              className="btn btn-primary"
 | 
			
		||||
              onClick={() => props.confirm()}
 | 
			
		||||
            >
 | 
			
		||||
              Yes
 | 
			
		||||
              {t('common:Yes')}
 | 
			
		||||
            </button>
 | 
			
		||||
            <button
 | 
			
		||||
              type="button"
 | 
			
		||||
              className="btn btn-secondary"
 | 
			
		||||
              onClick={() => props.close()}
 | 
			
		||||
            >
 | 
			
		||||
              No
 | 
			
		||||
              {t('common:No')}
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,7 @@ export default class StatsCharts extends React.PureComponent {
 | 
			
		||||
                    ''
 | 
			
		||||
                  )
 | 
			
		||||
                }
 | 
			
		||||
                name={t(`sports:${s.label}`)}
 | 
			
		||||
              />
 | 
			
		||||
            ))}
 | 
			
		||||
          </BarChart>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ import StaticMap from '../Common/StaticMap'
 | 
			
		||||
import { getDateWithTZ } from '../../utils'
 | 
			
		||||
 | 
			
		||||
export default function ActivityCard(props) {
 | 
			
		||||
  const { activity, sports, user } = props
 | 
			
		||||
  const { activity, sports, t, user } = props
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="card activity-card text-center">
 | 
			
		||||
@@ -14,7 +14,7 @@ export default function ActivityCard(props) {
 | 
			
		||||
        <Link to={`/activities/${activity.id}`}>
 | 
			
		||||
          {sports
 | 
			
		||||
            .filter(sport => sport.id === activity.sport_id)
 | 
			
		||||
            .map(sport => sport.label)}{' '}
 | 
			
		||||
            .map(sport => t(`sports:${sport.label}`))}{' '}
 | 
			
		||||
          -{' '}
 | 
			
		||||
          {format(
 | 
			
		||||
            getDateWithTZ(activity.activity_date, user.timezone),
 | 
			
		||||
@@ -31,8 +31,8 @@ export default function ActivityCard(props) {
 | 
			
		||||
          )}
 | 
			
		||||
          <div className="col">
 | 
			
		||||
            <p>
 | 
			
		||||
              <i className="fa fa-clock-o" aria-hidden="true" /> Duration:{' '}
 | 
			
		||||
              {activity.moving}
 | 
			
		||||
              <i className="fa fa-clock-o" aria-hidden="true" />{' '}
 | 
			
		||||
              {t('activities:Duration')}: {activity.moving}
 | 
			
		||||
              {activity.map ? (
 | 
			
		||||
                <span>
 | 
			
		||||
                  <br />
 | 
			
		||||
@@ -41,8 +41,8 @@ export default function ActivityCard(props) {
 | 
			
		||||
              ) : (
 | 
			
		||||
                ' - '
 | 
			
		||||
              )}
 | 
			
		||||
              <i className="fa fa-road" aria-hidden="true" /> Distance:{' '}
 | 
			
		||||
              {activity.distance} km
 | 
			
		||||
              <i className="fa fa-road" aria-hidden="true" />{' '}
 | 
			
		||||
              {t('activities:Distance')}: {activity.distance} km
 | 
			
		||||
            </p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,13 @@
 | 
			
		||||
import React from 'react'
 | 
			
		||||
import { Link } from 'react-router-dom'
 | 
			
		||||
 | 
			
		||||
import { formatRecord } from '../../utils/activities'
 | 
			
		||||
import { formatRecord, translateSports } from '../../utils/activities'
 | 
			
		||||
 | 
			
		||||
export default function RecordsCard(props) {
 | 
			
		||||
  const { records, sports, t, user } = props
 | 
			
		||||
  const translatedSports = translateSports(sports, t)
 | 
			
		||||
  const recordsBySport = records.reduce((sportList, record) => {
 | 
			
		||||
    const sport = sports.find(s => s.id === record.sport_id)
 | 
			
		||||
    const sport = translatedSports.find(s => s.id === record.sport_id)
 | 
			
		||||
    if (sportList[sport.label] === void 0) {
 | 
			
		||||
      sportList[sport.label] = {
 | 
			
		||||
        img: sport.img,
 | 
			
		||||
@@ -19,11 +20,13 @@ export default function RecordsCard(props) {
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="card activity-card">
 | 
			
		||||
      <div className="card-header">Personal records</div>
 | 
			
		||||
      <div className="card-header">{t('activities:Personal records')}</div>
 | 
			
		||||
      <div className="card-body">
 | 
			
		||||
        {Object.keys(recordsBySport).length === 0
 | 
			
		||||
          ? t('common:No records.')
 | 
			
		||||
          : Object.keys(recordsBySport).map(sportLabel => (
 | 
			
		||||
          : Object.keys(recordsBySport)
 | 
			
		||||
              .sort()
 | 
			
		||||
              .map(sportLabel => (
 | 
			
		||||
                <table
 | 
			
		||||
                  className="table table-borderless table-sm record-table"
 | 
			
		||||
                  key={sportLabel}
 | 
			
		||||
@@ -43,7 +46,7 @@ export default function RecordsCard(props) {
 | 
			
		||||
                  <tbody>
 | 
			
		||||
                    {recordsBySport[sportLabel].records.map(rec => (
 | 
			
		||||
                      <tr key={rec.id}>
 | 
			
		||||
                      <td>{rec.record_type}</td>
 | 
			
		||||
                        <td>{t(`activities:${rec.record_type}`)}</td>
 | 
			
		||||
                        <td className="text-right">{rec.value}</td>
 | 
			
		||||
                        <td className="text-right">
 | 
			
		||||
                          <Link to={`/activities/${rec.activity_id}`}>
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,7 @@ class DashBoard extends React.Component {
 | 
			
		||||
                        activity={activity}
 | 
			
		||||
                        key={activity.id}
 | 
			
		||||
                        sports={sports}
 | 
			
		||||
                        t={t}
 | 
			
		||||
                        user={user}
 | 
			
		||||
                      />
 | 
			
		||||
                    ))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,55 @@
 | 
			
		||||
{
 | 
			
		||||
  "Activity Date": "Activity Date",
 | 
			
		||||
  "Add a workout": "Add a workout",
 | 
			
		||||
  "Are you sure you want to delete this activity?": "Are you sure you want to delete this activity?",
 | 
			
		||||
  "Ave. speed": "Ave. speed",
 | 
			
		||||
  "Ascent": "Ascent",
 | 
			
		||||
  "Average speed": "Average speed",
 | 
			
		||||
  "Confirmation": "Confirmation",
 | 
			
		||||
  "data from gpx, without any cleaning": "data from gpx, without any cleaning",
 | 
			
		||||
  "Date": "Date",
 | 
			
		||||
  "Delete activity": "Delete activity",
 | 
			
		||||
  "Descent": "Descent",
 | 
			
		||||
  "Distance": "Distance",
 | 
			
		||||
  "distance": "distance",
 | 
			
		||||
  "Duration": "Duration",
 | 
			
		||||
  "duration": "duration",
 | 
			
		||||
  "Edit a workout": "Edit a workout",
 | 
			
		||||
  "Edit activity": "Edit activity",
 | 
			
		||||
  "elevation": "elevation",
 | 
			
		||||
  "End": "End",
 | 
			
		||||
  "Farest distance": "Farest distance",
 | 
			
		||||
  "Filter": "Filter",
 | 
			
		||||
  "From": "From",
 | 
			
		||||
  "gpxFile": "<strong>gpx</strong> file",
 | 
			
		||||
  "Longest duration": "Longest duration",
 | 
			
		||||
  "Max. altitude" : "Max. altitude",
 | 
			
		||||
  "Max. speed": "Max. speed",
 | 
			
		||||
  "Min. altitude": "Min. altitude",
 | 
			
		||||
  "no folder inside": "no folder inside",
 | 
			
		||||
  "files max": "files max",
 | 
			
		||||
  "max size": "max size",
 | 
			
		||||
  "No data to display": "No data to display",
 | 
			
		||||
  "No Map": "No Map",
 | 
			
		||||
  "No next activity": "No next activity",
 | 
			
		||||
  "No next segment": "No next segment",
 | 
			
		||||
  "No notes": "No notes",
 | 
			
		||||
  "No previous activity": "No previous activity",
 | 
			
		||||
  "No previous segment": "No previous segment",
 | 
			
		||||
  "Notes": "Notes",
 | 
			
		||||
  "pauses": "pauses",
 | 
			
		||||
  "Personal records": "Personal records",
 | 
			
		||||
  "See next activity": "See next activity",
 | 
			
		||||
  "See next segment": "See next segment",
 | 
			
		||||
  "See previous activity": "See previous activity",
 | 
			
		||||
  "See previous segment": "See previous segment",
 | 
			
		||||
  "segment": "segment",
 | 
			
		||||
  "Segments": "Segments",
 | 
			
		||||
  "speed": "speed",
 | 
			
		||||
  "Start": "Start",
 | 
			
		||||
  "Title": "Title",
 | 
			
		||||
  "To": "To",
 | 
			
		||||
  "total duration": "total duration",
 | 
			
		||||
  "with gpx file": "with gpx file",
 | 
			
		||||
  "without gpx file": "without gpx file",
 | 
			
		||||
  "zipFile": "or <strong> zip</strong> file containing <strong>gpx </strong> files"
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
  "days": "days",
 | 
			
		||||
  "Login": "Login",
 | 
			
		||||
  "Logout": "Logout",
 | 
			
		||||
  "No": "No",
 | 
			
		||||
  "No records.": "No records.",
 | 
			
		||||
  "No workouts.": "No workouts.",
 | 
			
		||||
  "Register": "Register",
 | 
			
		||||
@@ -19,5 +20,6 @@
 | 
			
		||||
  "Workout": "Workout",
 | 
			
		||||
  "Workouts": "Workouts",
 | 
			
		||||
  "workout": "workout",
 | 
			
		||||
  "workouts": "workouts"
 | 
			
		||||
  "workouts": "workouts",
 | 
			
		||||
  "Yes": "Yes"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,55 @@
 | 
			
		||||
{
 | 
			
		||||
  "Activity Date": "Date de l'activité",
 | 
			
		||||
  "Add a workout": "Ajouter une activité",
 | 
			
		||||
  "Are you sure you want to delete this activity?": "Etes-vous sûr de vouloir supprimer cette activité ?",
 | 
			
		||||
  "Ave. speed": "Vitesse moyenne",
 | 
			
		||||
  "Ascent": "Dénivelé positif",
 | 
			
		||||
  "Average speed": "Vitesse moyenne",
 | 
			
		||||
  "Confirmation": "Confirmation",
 | 
			
		||||
  "data from gpx, without any cleaning": "données issues du fichier gpx, sans correction",
 | 
			
		||||
  "Date": "Date",
 | 
			
		||||
  "Delete activity": "Supprimer l'activité",
 | 
			
		||||
  "Descent": "Dénivelé négatif",
 | 
			
		||||
  "Distance": "Distance",
 | 
			
		||||
  "distance": "distance",
 | 
			
		||||
  "Duration": "Durée",
 | 
			
		||||
  "duration": "durée",
 | 
			
		||||
  "Edit a workout": "Editer une activité",
 | 
			
		||||
  "Edit activity": "Editer une activity",
 | 
			
		||||
  "elevation": "altitude",
 | 
			
		||||
  "End": "Arrivée",
 | 
			
		||||
  "Farest distance": "Distance la + longue",
 | 
			
		||||
  "Filter": "Filtrer",
 | 
			
		||||
  "From": "A partir de",
 | 
			
		||||
  "gpxFile": "fichier <strong>gpx</strong>",
 | 
			
		||||
  "Longest duration": "Durée la + longue",
 | 
			
		||||
  "Max. altitude" : "Altitude max",
 | 
			
		||||
  "Max. speed": "Vitesse max",
 | 
			
		||||
  "Min. altitude": "Altitude min",
 | 
			
		||||
  "no folder inside": "pas de répertoire",
 | 
			
		||||
  "files max": " fichiers max",
 | 
			
		||||
  "max size": "taille max",
 | 
			
		||||
  "No data to display": "Pas de données à afficher",
 | 
			
		||||
  "No Map": "Pas de carte",
 | 
			
		||||
  "No next activity": "Pas d'activité suivante",
 | 
			
		||||
  "No next segment": "Pas de segment suivant",
 | 
			
		||||
  "No notes": "Pas de notes",
 | 
			
		||||
  "No previous activity": "Pas d'activité précédente",
 | 
			
		||||
  "No previous segment": "Pas de segment précédent",
 | 
			
		||||
  "Notes": "Notes",
 | 
			
		||||
  "pauses": "pauses",
 | 
			
		||||
  "Personal records": "Records personnels",
 | 
			
		||||
  "See next activity": "Voir l'activité suivante",
 | 
			
		||||
  "See next segment": "Voir le segment suivant",
 | 
			
		||||
  "See previous activity": "Voir l'activité précédente",
 | 
			
		||||
  "See previous segment": "Voir le segment précédent",
 | 
			
		||||
  "segment": "segment",
 | 
			
		||||
  "Segments": "Segments",
 | 
			
		||||
  "Start": "Départ",
 | 
			
		||||
  "speed": "vitesse",
 | 
			
		||||
  "Title": "Titre",
 | 
			
		||||
  "To": "Jusqu'au",
 | 
			
		||||
  "total duration": "durée totale",
 | 
			
		||||
  "with gpx file": "avec un fichier gpx",
 | 
			
		||||
  "without gpx file": "sans fichier gpx",
 | 
			
		||||
  "zipFile": "ou un fichier <strong> zip</strong> contenant des fichiers <strong>gpx</strong>"
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
  "days": "jours",
 | 
			
		||||
  "Login": "Se connecter",
 | 
			
		||||
  "Logout": "Se déconnecter",
 | 
			
		||||
  "No": "Non",
 | 
			
		||||
  "No records.": "Pas de records.",
 | 
			
		||||
  "No workouts.": "Pas d'activités.",
 | 
			
		||||
  "Register": "S'inscrire",
 | 
			
		||||
@@ -19,5 +20,6 @@
 | 
			
		||||
  "Workout": "Activité",
 | 
			
		||||
  "Workouts": "Activités",
 | 
			
		||||
  "workout": "activité",
 | 
			
		||||
  "workouts": "activités"
 | 
			
		||||
  "workouts": "activités",
 | 
			
		||||
  "Yes": "Oui"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,10 @@ export const activityColors = [
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const recordsLabels = [
 | 
			
		||||
  { record_type: 'AS', label: 'Avg speed' },
 | 
			
		||||
  { record_type: 'AS', label: 'Ave. speed' },
 | 
			
		||||
  { record_type: 'FD', label: 'Farest distance' },
 | 
			
		||||
  { record_type: 'LD', label: 'Longest duration' },
 | 
			
		||||
  { record_type: 'MS', label: 'Max speed' },
 | 
			
		||||
  { record_type: 'MS', label: 'Max. speed' },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export const getGeoJson = gpxContent => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user