Merge branch 'master' into v0.3.0

Conflicts:
	VERSION
	docs/.buildinfo
	docs/_static/documentation_options.js
	docs/api/activities.html
	docs/api/auth.html
	docs/api/index.html
	docs/api/records.html
	docs/api/sports.html
	docs/api/stats.html
	docs/api/users.html
	docs/changelog.html
	docs/features.html
	docs/genindex.html
	docs/http-routingtable.html
	docs/index.html
	docs/installation.html
	docs/objects.inv
	docs/search.html
	docs/searchindex.js
	docs/troubleshooting/administrator.html
	docs/troubleshooting/index.html
	docs/troubleshooting/user.html
	fittrackee_api/poetry.lock
	fittrackee_client/src/utils/index.js
	yarn.lock
This commit is contained in:
Sam
2020-01-30 22:45:50 +01:00
45 changed files with 1850 additions and 1099 deletions

View File

@ -98,6 +98,12 @@ label {
max-height: 20px;
}
.activity-map {
background-color: #eaeaea;
height: 225px;
width: 400px;
}
.activity-no-map {
background-color: #eaeaea;
color: #666666;
@ -257,6 +263,13 @@ label {
.custom-fa-small {
font-size: 0.8em;
margin-left: -0.8em;
}
@media only screen and (max-width: 992px) {
.custom-fa-small {
font-size: 0.6em;
}
}
.custom-tooltip {
@ -365,9 +378,9 @@ label {
}
.map-attribution {
bottom: 0;
font-size: 11px;
position:relative;
top: -15px;
position: absolute;
}
.map-attribution-text {
@ -441,8 +454,18 @@ label {
color: #ffffff;
}
.timezone-custom-height {
height: calc(2.25rem + 14px);
.timezone-custom {
font-size: .9em !important;
height: inherit !important;
}
.timezone-custom input {
border: 0 !important;
padding: 5px 1px !important;
}
.timezone-custom ul {
background: white;
}
.timezone-picker {
@ -549,7 +572,6 @@ label {
position: relative;
height: 3em;
border-right: 1px solid var(--border-color);
overflow: hidden;
background: var(--neutral-color);
}
@ -602,3 +624,59 @@ label {
.calendar .body .weekend {
background: #f5f5f5;
}
.calendar-activity,
.calendar-more {
display: none;
}
.calendar-more {
color: #405976;
font-size: .7em;
margin-left: 0.3em;
}
.calendar-display-more {
background: whitesmoke;
border-radius: 4px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
margin-bottom: 10px;
padding: 10px 15px;
position: absolute;
min-width: 52px;
z-index: 1000;
}
.calendar-activity-more {
display: none;
}
@media only screen and (max-width: 992px) {
.calendar-activity:nth-child(-n+2),
.calendar-activity:nth-child(n+3) ~ .calendar-more,
.calendar-activity-more:nth-child(n+3) {
display: inline-block;
}
}
@media only screen and (min-width: 992px) and (max-width: 1200px) {
.calendar-activity:nth-child(-n+4),
.calendar-activity:nth-child(n+5) ~ .calendar-more,
.calendar-activity-more:nth-child(n+5) {
display: inline-block;
}
}
@media only screen and (min-width: 1200px) {
.calendar-activity:nth-child(-n+6),
.calendar-activity:nth-child(n+7) ~ .calendar-more,
.calendar-activity-more:nth-child(n+7) {
display: inline-block;
}
}

View File

@ -5,17 +5,14 @@ import { apiUrl } from '../../utils'
export default class StaticMap extends React.PureComponent {
render() {
const { activity, display } = this.props
const attributionStyle =
display === 'list' ? 'map-attribution-list' : 'map-attribution text-right'
return (
<>
<div className={`activity-map${display === 'list' ? '-list' : ''}`}>
<img
className="activity-map"
src={`${apiUrl}activities/map/${activity.map}?${Date.now()}`}
alt="activity map"
/>
<div className={attributionStyle}>
<div className={`map-attribution${display === 'list' ? '-list' : ''}`}>
<span className="map-attribution-text">©</span>
<a
className="map-attribution-text"
@ -26,7 +23,7 @@ export default class StaticMap extends React.PureComponent {
OpenStreetMap
</a>
</div>
</>
</div>
)
}
}

View File

@ -13,13 +13,12 @@ import {
subMonths,
} from 'date-fns'
import { enGB, fr } from 'date-fns/locale'
import React, { Fragment } from 'react'
import React from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import CalendarActivities from './CalendarActivities'
import { getMonthActivities } from '../../actions/activities'
import { getDateWithTZ } from '../../utils'
import { recordsLabels } from '../../utils/activities'
const getStartAndEndMonth = (date, weekStartOnMonday) => {
const monthStart = startOfMonth(date)
@ -114,36 +113,11 @@ class Calendar extends React.Component {
<div className={`col cell ${isWeekEnd ? ' weekend' : ''}`} key={day}>
<div className={`img${isDisabled}`}>
<span className="number">{formattedDate}</span>
{dayActivities.map(act => (
<Link key={act.id} to={`/activities/${act.id}`}>
<Fragment>
<img
alt="activity sport logo"
className={`activity-sport ${isDisabled}`}
src={sports
.filter(s => s.id === act.sport_id)
.map(s => s.img)}
title={act.title}
/>
{act.records.length > 0 && (
<sup>
<i
className="fa fa-trophy custom-fa-small"
aria-hidden="true"
title={act.records.map(
rec =>
` ${
recordsLabels.filter(
r => r.record_type === rec.record_type
)[0].label
}`
)}
/>
</sup>
)}
</Fragment>
</Link>
))}
<CalendarActivities
dayActivities={dayActivities}
isDisabled={isDisabled}
sports={sports}
/>
</div>
</div>
)

View File

@ -0,0 +1,59 @@
import React from 'react'
import CalendarActivity from './CalendarActivity'
export default class CalendarActivities extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
isHidden: true,
}
}
handleDisplayMore() {
this.setState({
isHidden: !this.state.isHidden,
})
}
render() {
const { dayActivities, isDisabled, sports } = this.props
const { isHidden } = this.state
return (
<div>
{dayActivities.map(act => (
<CalendarActivity
key={act.id}
activity={act}
isDisabled={isDisabled}
isMore=""
sportImg={sports.filter(s => s.id === act.sport_id).map(s => s.img)}
/>
))}
{dayActivities.length > 2 && (
<i
className={`fa fa-${isHidden ? 'plus' : 'times'} calendar-more`}
aria-hidden="true"
onClick={() => this.handleDisplayMore()}
title="show more activities"
/>
)}
{!isHidden && (
<div className="calendar-display-more">
{dayActivities.map(act => (
<CalendarActivity
key={act.id}
activity={act}
isDisabled={isDisabled}
isMore="-more"
sportImg={sports
.filter(s => s.id === act.sport_id)
.map(s => s.img)}
/>
))}
</div>
)}
</div>
)
}
}

View File

@ -0,0 +1,39 @@
import React from 'react'
import { Link } from 'react-router-dom'
import { recordsLabels } from '../../utils/activities'
export default function CalendarActivity(props) {
const { activity, isDisabled, isMore, sportImg } = props
return (
<Link
className={`calendar-activity${isMore}`}
to={`/activities/${activity.id}`}
>
<>
<img
alt="activity sport logo"
className={`activity-sport ${isDisabled}`}
src={sportImg}
title={activity.title}
/>
{activity.records.length > 0 && (
<sup>
<i
className="fa fa-trophy custom-fa-small"
aria-hidden="true"
title={activity.records.map(
rec =>
` ${
recordsLabels.filter(
r => r.record_type === rec.record_type
)[0].label
}`
)}
/>
</sup>
)}
</>
</Link>
)
}

View File

@ -205,7 +205,7 @@ class ProfileEdit extends React.Component {
<label>
{t('user:Timezone')}:
<TimezonePicker
className="form-control timezone-custom-height"
className="form-control timezone-custom"
onChange={tz => {
const e = {
target: {