Client - update workout card on timeline and workout detail

This commit is contained in:
Sam
2021-09-27 15:34:36 +02:00
parent f8c0f89852
commit a7c268ca67
8 changed files with 148 additions and 28 deletions

View File

@ -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">

View File

@ -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;
}
}
}
}

View File

@ -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>

View File

@ -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') }}:

View File

@ -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) {