Client - update workout card on timeline and workout detail
This commit is contained in:
@ -3,9 +3,7 @@
|
||||
<div
|
||||
class="bg-map-image"
|
||||
:style="{
|
||||
backgroundImage: `url(${getApiUrl()}workouts/map/${
|
||||
workout.map
|
||||
}?${Date.now()})`,
|
||||
backgroundImage: `url(${getApiUrl()}workouts/map/${workout.map})`,
|
||||
}"
|
||||
/>
|
||||
<div class="map-attribution">
|
||||
|
@ -13,10 +13,13 @@
|
||||
<div v-else class="no-picture">
|
||||
<i class="fa fa-user-circle-o" aria-hidden="true" />
|
||||
</div>
|
||||
<span class="workout-user-name">{{ user.username }}</span>
|
||||
<span v-if="user.username" class="workout-user-name">
|
||||
{{ user.username }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="workout-date"
|
||||
v-if="workout && user"
|
||||
:title="
|
||||
format(
|
||||
getDateWithTZ(workout.workout_date, user.timezone),
|
||||
@ -34,12 +37,22 @@
|
||||
</div>
|
||||
<div
|
||||
class="workout-map"
|
||||
v-if="workout.with_gpx"
|
||||
:class="{ 'no-cursor': !workout }"
|
||||
@click="
|
||||
$router.push({ name: 'Workout', params: { workoutId: workout.id } })
|
||||
workout
|
||||
? $router.push({
|
||||
name: 'Workout',
|
||||
params: { workoutId: workout.id },
|
||||
})
|
||||
: null
|
||||
"
|
||||
>
|
||||
<StaticMap :workout="workout"></StaticMap>
|
||||
<div v-if="workout">
|
||||
<StaticMap v-if="workout.with_gpx" :workout="workout" />
|
||||
<div v-else class="no-map">
|
||||
{{ t('workouts.NO_MAP') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="workout-data"
|
||||
@ -48,15 +61,20 @@
|
||||
"
|
||||
>
|
||||
<div>
|
||||
<img class="sport-img" alt="workout sport logo" :src="sport.img" />
|
||||
<img
|
||||
v-if="sport"
|
||||
class="sport-img"
|
||||
alt="workout sport logo"
|
||||
:src="sport.img"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<i class="fa fa-clock-o" aria-hidden="true" />
|
||||
{{ workout.moving }}
|
||||
<span v-if="workout">{{ workout.moving }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<i class="fa fa-road" aria-hidden="true" />
|
||||
{{ workout.distance }} km
|
||||
<span v-if="workout">{{ workout.distance }} km</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -88,7 +106,7 @@
|
||||
props: {
|
||||
workout: {
|
||||
type: Object as PropType<IWorkout>,
|
||||
required: true,
|
||||
required: false,
|
||||
},
|
||||
user: {
|
||||
type: Object as PropType<IAuthUserProfile>,
|
||||
@ -96,12 +114,13 @@
|
||||
},
|
||||
sport: {
|
||||
type: Object as PropType<ISport>,
|
||||
required: true,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const { t } = useI18n()
|
||||
const store = useStore()
|
||||
|
||||
const userPictureUrl: ComputedRef<string> = computed(() =>
|
||||
props.user.picture
|
||||
? `${getApiUrl()}/users/${props.user.username}/picture?${Date.now()}`
|
||||
@ -157,6 +176,18 @@
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.workout-map {
|
||||
background-color: var(--workout-no-map-bg-color);
|
||||
height: 150px;
|
||||
.no-map {
|
||||
line-height: 150px;
|
||||
}
|
||||
.bg-map-image {
|
||||
height: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.workout-data {
|
||||
display: flex;
|
||||
padding-top: $default-padding * 0.5;
|
||||
@ -173,6 +204,12 @@
|
||||
.workout-data {
|
||||
cursor: pointer;
|
||||
}
|
||||
.no-cursor {
|
||||
cursor: default;
|
||||
}
|
||||
.fa {
|
||||
padding-right: $default-padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,16 @@
|
||||
<div class="timeline">
|
||||
<div class="section-title">{{ t('workouts.LATEST_WORKOUTS') }}</div>
|
||||
<WorkoutCard
|
||||
v-for="workout in workouts"
|
||||
:workout="workout"
|
||||
:sport="sports.filter((s) => s.id === workout.sport_id)[0]"
|
||||
v-for="index in [...Array(displayedWorkoutsCount).keys()]"
|
||||
:workout="workouts.length > 0 ? workouts[index] : null"
|
||||
:sport="
|
||||
workouts.length > 0
|
||||
? sports.filter((s) => s.id === workouts[index].sport_id)[0]
|
||||
: null
|
||||
"
|
||||
:user="user"
|
||||
:key="workout.id"
|
||||
></WorkoutCard>
|
||||
:key="index"
|
||||
/>
|
||||
<div v-if="workouts.length === 0" class="no-workouts">
|
||||
{{ t('workouts.NO_WORKOUTS') }}
|
||||
</div>
|
||||
@ -16,11 +20,11 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
computed,
|
||||
ComputedRef,
|
||||
PropType,
|
||||
computed,
|
||||
defineComponent,
|
||||
onBeforeMount,
|
||||
PropType,
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@ -46,19 +50,25 @@
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
setup(props) {
|
||||
const store = useStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
const per_page = 5
|
||||
const displayedWorkoutsCount =
|
||||
props.user.nb_workouts >= per_page ? per_page : props.user.nb_workouts
|
||||
onBeforeMount(() =>
|
||||
store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, { page: 1 })
|
||||
store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, {
|
||||
page: 1,
|
||||
per_page,
|
||||
})
|
||||
)
|
||||
|
||||
const workouts: ComputedRef<IWorkout[]> = computed(
|
||||
() => store.getters[WORKOUTS_STORE.GETTERS.USER_WORKOUTS]
|
||||
)
|
||||
|
||||
return { workouts, t }
|
||||
return { displayedWorkoutsCount, per_page, workouts, t }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
@ -28,7 +28,7 @@
|
||||
class="workout-data"
|
||||
v-if="workoutObject.maxAlt !== null && workoutObject.minAlt !== null"
|
||||
>
|
||||
<img class="mountains" src="/img/misc/mountains.svg" />
|
||||
<img class="mountains" src="/img/workouts/mountains.svg" />
|
||||
{{ t('workouts.MIN_ALTITUDE') }}: <span>{{ workoutObject.minAlt }} m</span
|
||||
><br />
|
||||
{{ t('workouts.MAX_ALTITUDE') }}:
|
||||
|
@ -138,12 +138,7 @@
|
||||
width: 600px;
|
||||
}
|
||||
.no-map {
|
||||
text-align: center;
|
||||
vertical-align: center;
|
||||
font-style: italic;
|
||||
line-height: 400px;
|
||||
color: var(--workout-no-map-color);
|
||||
background-color: var(--workout-no-map-bg-color);
|
||||
}
|
||||
|
||||
@media screen and (max-width: $small-limit) {
|
||||
|
Reference in New Issue
Block a user