API & Client: Activity display update

This commit is contained in:
Sam
2018-05-16 23:52:55 +02:00
parent 3047655e1f
commit ca80a8b6d5
19 changed files with 229 additions and 91 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -7,9 +7,10 @@
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link
href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
rel="stylesheet"
>
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB"
crossorigin="anonymous">
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/fork-awesome@1.0.11/css/fork-awesome.min.css"

View File

@ -7,6 +7,7 @@ import ActivityMap from './ActivityMap'
import CustomModal from './../Others/CustomModal'
import { getData } from '../../actions'
import { deleteActivity } from '../../actions/activities'
import { formatActivityDate } from '../../utils'
class ActivityDisplay extends React.Component {
constructor(props, context) {
@ -24,14 +25,18 @@ class ActivityDisplay extends React.Component {
const { activities, message, onDeleteActivity, sports } = this.props
const { displayModal } = this.state
const [activity] = activities
const title = activity ? activity.title : 'Activity'
const [sport] = activity
? sports.filter(s => s.id === activity.sport_id)
: []
const activityDate = activity
? formatActivityDate(activity.activity_date)
: null
return (
<div>
<div className="activity-page">
<Helmet>
<title>mpwo - Activity</title>
<title>mpwo - {title}</title>
</Helmet>
<h1 className="page-title">
Activity
</h1>
{message ? (
<code>{message}</code>
) : (
@ -46,79 +51,129 @@ class ActivityDisplay extends React.Component {
}}
close={() => this.setState({ displayModal: false })}
/>}
{activity && sports.length > 0 && (
{activity && sport && (
<div className="row">
<div className="col-md-6">
<div className="col">
<div className="card">
<div className="card-header">
{sports.filter(sport => sport.id === activity.sport_id)
.map(sport => sport.label)} -{' '}
{activity.activity_date}{' '}
<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 })}
/>
<div className="row">
<div className="col-auto col-activity-logo">
<img
className="sport-img-medium"
src={sport.img}
alt="sport logo"
/>
</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_time}`}
</span>
)}
</div>
</div>
</div>
<div className="card-body">
<p>
<i
className="fa fa-calendar custom-fa"
aria-hidden="true"
/>
Start at {activity.activity_date}
</p>
<p>
<i className="fa fa-clock-o custom-fa" aria-hidden="true" />
Duration: {activity.duration} {' '}
{activity.pauses !== '0:00:00' &&
activity.pauses !== null && (
`(pauses: ${activity.pauses})`
<div className="row">
{activity.with_gpx && (
<div className="col-8">
<ActivityMap activity={activity} />
</div>
)}
</p>
<p>
<i className="fa fa-road custom-fa" aria-hidden="true" />
Distance: {activity.distance} km</p>
<p>
<i
className="fa fa-tachometer custom-fa"
aria-hidden="true"
/>
Average speed: {activity.ave_speed} km/h -{' '}
Max speed : {activity.max_speed} km/h
</p>
{activity.min_alt && activity.max_alt && (
<p><i className="fi-mountains custom-fa" />
Min altitude: {activity.min_alt}m -{' '}
Max altitude: {activity.max_alt}m
</p>
)}
{activity.ascent && activity.descent && (
<p><i className="fa fa-location-arrow custom-fa" />
Ascent: {activity.ascent}m -{' '}
Descent: {activity.descent}m
</p>
)}
</div>
</div>
</div>
<div className="col-md-6">
<div className="card">
<div className="card-header">
Map
</div>
<div className="card-body">
{activity.with_gpx ? (
<ActivityMap activity={activity} />
) : (
'No map'
)}
<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>

View File

@ -36,7 +36,7 @@ class ActivityMap extends React.Component {
<Map
zoom={this.state.zoom}
bounds={bounds}
boundsOptions={{ padding: [20, 20] }}
boundsOptions={{ padding: [10, 10] }}
>
<TileLayer
// eslint-disable-next-line max-len

View File

@ -51,12 +51,21 @@ class AdminDetail extends React.Component {
<div className="form-group" key={key}>
<label>
{key}:
<input
{key === 'img' ? (
<img
src={results[0][key]
? results[0][key]
: '/img/photo.png'}
alt="property"
/>
) : (
<input
className="form-control input-lg"
name={key}
readOnly={key === 'id' || !isInEdition}
defaultValue={results[0][key]}
/>
/>
)}
</label>
</div>
))

View File

@ -56,6 +56,16 @@ export default function AdminPage(props) {
</Link>
</th>
)
} else if (key === 'img') {
return (<td key={key}>
<img
className="admin-img"
src={result[key]
? result[key]
: '/img/photo.png'}
alt="logo"
/>
</td>)
}
return <td key={key}>{result[key]}</td>
})

View File

@ -61,12 +61,33 @@ input, textarea {
margin-bottom: 15px;
}
.activity-date {
font-size: 0.75em;
}
.activity-page {
margin-top: 20px;
}
.add-activity {
margin-top: 50px;
}
.admin-img {
max-width: 35px;
max-height: 35px;
}
.col-activity-logo{
padding-right: 0;
}
.fa-trophy {
color: goldenrod;
}
.leaflet-container {
height: 240px;
height: 400px;
}
.radioLabel {
@ -78,7 +99,7 @@ input, textarea {
border-radius: 5px;
max-width: 500px;
margin: 20% auto;
z-index: 1050;
z-index: 100;
}
.custom-modal-backdrop {
@ -89,13 +110,23 @@ input, textarea {
right: 0;
background-color: rgba(0,0,0,0.3);
padding: 50px;
z-index: 1040;
z-index: 90;
}
.custom-fa {
margin-right: 5px;
}
.sport-img {
max-width: 35px;
max-height: 35px;
}
.sport-img-medium {
max-width: 45px;
max-height: 45px;
}
.unlink {
color: black;
}

View File

@ -27,9 +27,15 @@ export const getGeoJson = gpxContent => {
}
export const formatActivityDate = activityDateTime => {
const dateTime = parse(activityDateTime)
if (activityDateTime) {
const dateTime = parse(activityDateTime)
return {
activity_date: format(dateTime, 'YYYY-MM-DD'),
activity_time: activityDateTime.match(/[0-2][0-9]:[0-5][0-9]/)[0]
}
}
return {
activity_date: format(dateTime, 'YYYY-MM-DD'),
activity_time: activityDateTime.match(/[0-2][0-9]:[0-5][0-9]/)[0]
activity_date: null,
activity_time: null,
}
}