264 lines
6.5 KiB
Vue
Raw Normal View History

2021-09-20 12:18:40 +02:00
<template>
<div class="timeline-workout">
2021-10-05 19:02:08 +02:00
<div class="box">
<div class="workout-user-date">
<div class="workout-user">
2021-11-01 20:48:22 +01:00
<UserPicture :user="user" />
<router-link
v-if="user.username"
class="workout-user-name"
:to="{
name: 'User',
params: { username: user.username },
}"
>
2021-10-05 19:02:08 +02:00
{{ user.username }}
</router-link>
2021-09-20 12:18:40 +02:00
</div>
<router-link
class="workout-title"
v-if="workout.id"
:to="{
name: 'Workout',
params: { workoutId: workout.id },
}"
>
{{ workout.title }}
</router-link>
<div
2021-10-05 19:02:08 +02:00
class="workout-date"
v-if="workout.workout_date && user"
2021-10-05 19:02:08 +02:00
:title="
format(
getDateWithTZ(workout.workout_date, user.timezone),
'dd/MM/yyyy HH:mm'
)
"
>
2021-10-05 19:02:08 +02:00
{{
formatDistance(new Date(workout.workout_date), new Date(), {
addSuffix: true,
locale,
})
}}
2021-09-20 12:18:40 +02:00
</div>
2021-10-05 19:02:08 +02:00
</div>
<div
class="workout-map"
:class="{ 'no-cursor': !workout }"
@click="
workout.id
2021-10-05 19:02:08 +02:00
? $router.push({
name: 'Workout',
params: { workoutId: workout.id },
})
: null
"
>
<div v-if="workout">
<StaticMap v-if="workout.with_gpx" :workout="workout" />
<div v-else class="no-map">
2021-10-20 17:38:25 +02:00
{{ $t('workouts.NO_MAP') }}
2021-09-20 12:18:40 +02:00
</div>
</div>
2021-10-05 19:02:08 +02:00
</div>
<div
class="workout-data"
:class="{ 'without-gpx': workout && !workout.with_gpx }"
2021-10-05 19:02:08 +02:00
@click="
workout.id
? $router.push({
name: 'Workout',
params: { workoutId: workout.id },
})
: null
2021-10-05 19:02:08 +02:00
"
>
<div class="img">
<SportImage
v-if="sport.label"
:sport-label="sport.label"
:color="sport.color"
/>
2021-10-05 19:02:08 +02:00
</div>
<div class="data">
2021-10-05 19:02:08 +02:00
<i class="fa fa-clock-o" aria-hidden="true" />
<span v-if="workout">{{ workout.moving }}</span>
</div>
<div class="data">
2021-10-05 19:02:08 +02:00
<i class="fa fa-road" aria-hidden="true" />
<span v-if="workout">{{ workout.distance }} km</span>
</div>
<div class="data elevation" v-if="workout && workout.with_gpx">
<img
class="mountains"
src="/img/workouts/mountains.svg"
:alt="$t('workouts.ELEVATION')"
/>
<div class="data-values">
<span>{{ workout.min_alt }}/</span>
<span>{{ workout.max_alt }} m </span>
</div>
</div>
<div class="data altitude" v-if="workout && workout.with_gpx">
<i class="fa fa-location-arrow" aria-hidden="true" />
<div class="data-values">
<span>+ {{ workout.ascent }}/</span>
<span>- {{ workout.descent }} m </span>
</div>
</div>
2021-10-05 19:02:08 +02:00
</div>
</div>
2021-09-20 12:18:40 +02:00
</div>
</template>
<script setup lang="ts">
2021-09-20 12:18:40 +02:00
import { Locale, format, formatDistance } from 'date-fns'
import { ComputedRef, computed, toRefs, withDefaults } from 'vue'
2021-09-20 12:18:40 +02:00
import StaticMap from '@/components/Common/StaticMap.vue'
2021-11-01 20:48:22 +01:00
import UserPicture from '@/components/User/UserPicture.vue'
2021-09-20 12:18:40 +02:00
import { ROOT_STORE } from '@/store/constants'
import { ISport } from '@/types/sports'
2021-10-30 12:01:55 +02:00
import { IUserProfile } from '@/types/user'
2021-09-20 12:18:40 +02:00
import { IWorkout } from '@/types/workouts'
import { useStore } from '@/use/useStore'
import { getDateWithTZ } from '@/utils/dates'
interface Props {
user: IUserProfile
workout?: IWorkout
sport?: ISport
}
const props = withDefaults(defineProps<Props>(), {
workout: () => ({} as IWorkout),
sport: () => ({} as ISport),
2021-09-20 12:18:40 +02:00
})
const store = useStore()
const { user, workout, sport } = toRefs(props)
const locale: ComputedRef<Locale> = computed(
() => store.getters[ROOT_STORE.GETTERS.LOCALE]
)
2021-09-20 12:18:40 +02:00
</script>
<style lang="scss" scoped>
@import '~@/scss/base';
.mountains {
padding-right: $default-padding * 0.5;
}
2021-09-20 12:18:40 +02:00
.timeline-workout {
margin-bottom: $default-margin * 2;
2021-10-05 19:02:08 +02:00
.box {
flex-direction: column;
padding: 0;
.workout-user-date {
2021-09-20 12:18:40 +02:00
display: flex;
2021-10-05 19:02:08 +02:00
justify-content: space-between;
padding: $default-padding * 0.5 $default-padding;
.workout-user {
2021-09-20 12:18:40 +02:00
display: flex;
2021-11-01 20:48:22 +01:00
::v-deep(.user-picture) {
img {
height: 25px;
width: 25px;
}
.no-picture {
font-size: 1.5em;
}
}
2021-10-05 19:02:08 +02:00
.workout-user-name {
padding-left: 5px;
}
}
2021-10-05 19:02:08 +02:00
.workout-date {
font-size: 0.85em;
font-style: italic;
}
.workout-title {
display: block;
padding: 0 $default-padding;
@media screen and (max-width: $x-small-limit) {
display: none;
}
}
2021-10-05 19:02:08 +02:00
}
2021-10-05 19:02:08 +02:00
.workout-map {
background-color: var(--workout-no-map-bg-color);
height: 150px;
.no-map {
line-height: 150px;
2021-09-20 12:18:40 +02:00
}
2021-10-05 19:02:08 +02:00
::v-deep(.bg-map-image) {
height: 150px;
}
2021-10-05 19:02:08 +02:00
}
.workout-data {
display: flex;
padding: $default-padding * 0.5;
font-size: 0.9em;
2021-10-05 19:02:08 +02:00
.sport-img {
height: 25px;
width: 25px;
}
.img,
.data {
2021-10-05 19:02:08 +02:00
display: flex;
align-items: center;
.data-values {
display: flex;
flex-wrap: wrap;
}
}
.img {
justify-content: flex-end;
width: 10%;
}
.data {
justify-content: center;
width: 22%;
}
@media screen and (max-width: $x-small-limit) {
.img {
justify-content: center;
width: 20%;
}
.data {
justify-content: center;
width: 40%;
}
.altitude,
.elevation {
display: none;
}
}
&.without-gpx {
.img,
.data {
justify-content: center;
width: 33%;
}
}
2021-09-20 12:18:40 +02:00
}
2021-10-05 19:02:08 +02:00
.workout-map,
.workout-data {
cursor: pointer;
}
.no-cursor {
cursor: default;
}
.fa {
padding-right: $default-padding;
}
2021-09-20 12:18:40 +02:00
}
}
</style>