Client - display message when no workouts

This commit is contained in:
Sam 2021-10-05 17:52:36 +02:00
parent f68a257ff3
commit 95cf71055b
10 changed files with 71 additions and 12 deletions

View File

@ -0,0 +1,35 @@
<template>
<div class="no-workouts">
<div>
{{ t('workouts.NO_WORKOUTS') }}
<router-link to="/workouts/add">
{{ t('workouts.UPLOAD_FIRST_WORKOUT') }}
</router-link>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
export default defineComponent({
name: 'NoWorkouts',
setup() {
const { t } = useI18n()
return { t }
},
})
</script>
<style lang="scss" scoped>
@import '~@/scss/base.scss';
.no-workouts {
display: flex;
justify-content: center;
border: solid 1px var(--card-border-color);
border-radius: $border-radius;
padding: $default-padding;
margin: $default-margin;
}
</style>

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="start-chart"> <div class="start-chart">
<div v-if="labels.length === 0"> <div v-if="hideChartIfNoData && emptyStats">
{{ t('workouts.NO_WORKOUTS') }} {{ t('workouts.NO_WORKOUTS') }}
</div> </div>
<div v-else> <div v-else>
@ -99,6 +99,10 @@
type: Boolean, type: Boolean,
default: false, default: false,
}, },
hideChartIfNoData: {
type: Boolean,
default: false,
},
}, },
setup(props) { setup(props) {
const store = useStore() const store = useStore()
@ -162,6 +166,7 @@
() => formattedStats.value.datasets[displayedData.value] () => formattedStats.value.datasets[displayedData.value]
), ),
labels: computed(() => formattedStats.value.labels), labels: computed(() => formattedStats.value.labels),
emptyStats: computed(() => Object.keys(statistics.value).length === 0),
displayedData, displayedData,
t, t,
updateDisplayData, updateDisplayData,

View File

@ -20,9 +20,7 @@
:user="user" :user="user"
:key="workout.id" :key="workout.id"
/> />
<div v-if="workouts.length === 0" class="no-workouts"> <NoWorkouts v-if="workouts.length === 0" />
{{ t('workouts.NO_WORKOUTS') }}
</div>
<div v-if="moreWorkoutsExist" class="more-workouts"> <div v-if="moreWorkoutsExist" class="more-workouts">
<button @click="loadMoreWorkouts"> <button @click="loadMoreWorkouts">
{{ t('workouts.LOAD_MORE_WORKOUT') }} {{ t('workouts.LOAD_MORE_WORKOUT') }}
@ -43,6 +41,7 @@
} from 'vue' } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import NoWorkouts from '@/components/Common/NoWorkouts.vue'
import WorkoutCard from '@/components/Dashboard/Timeline/WorkoutCard.vue' import WorkoutCard from '@/components/Dashboard/Timeline/WorkoutCard.vue'
import { WORKOUTS_STORE } from '@/store/constants' import { WORKOUTS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import { ISport } from '@/types/sports'
@ -53,6 +52,7 @@
export default defineComponent({ export default defineComponent({
name: 'Timeline', name: 'Timeline',
components: { components: {
NoWorkouts,
WorkoutCard, WorkoutCard,
}, },
props: { props: {
@ -115,10 +115,7 @@
#timeline { #timeline {
margin-bottom: 20px; margin-bottom: 20px;
.no-workouts {
margin-bottom: $default-margin * 2;
padding: $default-padding;
}
.more-workouts { .more-workouts {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@ -8,6 +8,7 @@
:user="user" :user="user"
:chart-params="chartParams" :chart-params="chartParams"
:displayed-sport-ids="selectedSportIds" :displayed-sport-ids="selectedSportIds"
:hide-chart-if-no-data="true"
/> />
</template> </template>
</Card> </Card>

View File

@ -62,7 +62,10 @@
.user-records { .user-records {
.no-records { .no-records {
border: solid 1px var(--card-border-color);
border-radius: $border-radius;
padding: $default-padding; padding: $default-padding;
margin: $default-margin;
} }
} }
</style> </style>

View File

@ -123,6 +123,11 @@
@import '~@/scss/base'; @import '~@/scss/base';
#user-statistics { #user-statistics {
&.stats-disabled {
opacity: 0.3;
pointer-events: none;
}
::v-deep(.chart-radio) { ::v-deep(.chart-radio) {
justify-content: space-around; justify-content: space-around;
padding: $default-padding * 3 $default-padding padding: $default-padding * 3 $default-padding

View File

@ -93,6 +93,7 @@
</div> </div>
</template> </template>
</Card> </Card>
<NoWorkouts v-if="workouts.length === 0" />
<div v-if="moreWorkoutsExist" class="more-workouts"> <div v-if="moreWorkoutsExist" class="more-workouts">
<button @click="loadMoreWorkouts"> <button @click="loadMoreWorkouts">
{{ t('workouts.LOAD_MORE_WORKOUT') }} {{ t('workouts.LOAD_MORE_WORKOUT') }}
@ -116,6 +117,7 @@
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import Card from '@/components/Common/Card.vue' import Card from '@/components/Common/Card.vue'
import NoWorkouts from '@/components/Common/NoWorkouts.vue'
import SportImage from '@/components/Common/SportImage/index.vue' import SportImage from '@/components/Common/SportImage/index.vue'
import StaticMap from '@/components/Common/StaticMap.vue' import StaticMap from '@/components/Common/StaticMap.vue'
import { WORKOUTS_STORE } from '@/store/constants' import { WORKOUTS_STORE } from '@/store/constants'
@ -130,6 +132,7 @@
name: 'WorkoutsList', name: 'WorkoutsList',
components: { components: {
Card, Card,
NoWorkouts,
SportImage, SportImage,
StaticMap, StaticMap,
}, },
@ -211,6 +214,8 @@
::v-deep(.card) { ::v-deep(.card) {
.card-content { .card-content {
margin-bottom: 15px;
.workouts-table { .workouts-table {
/* responsive table, adapted from: */ /* responsive table, adapted from: */
/* https://uglyduck.ca/making-tables-responsive-with-minimal-css/ */ /* https://uglyduck.ca/making-tables-responsive-with-minimal-css/ */

View File

@ -51,6 +51,7 @@
"TITLE": "title", "TITLE": "title",
"TO": "to", "TO": "to",
"TOTAL_DURATION": "total duration", "TOTAL_DURATION": "total duration",
"UPLOAD_FIRST_WORKOUT": "Upload one!",
"WEATHER": { "WEATHER": {
"HUMIDITY": "humidity", "HUMIDITY": "humidity",
"TEMPERATURE": "temperature", "TEMPERATURE": "temperature",

View File

@ -51,6 +51,7 @@
"TITLE": "titre", "TITLE": "titre",
"TO": "jusqu'au", "TO": "jusqu'au",
"TOTAL_DURATION": "durée totale", "TOTAL_DURATION": "durée totale",
"UPLOAD_FIRST_WORKOUT": "Ajoutez votre première séance !",
"WEATHER": { "WEATHER": {
"HUMIDITY": "humidité", "HUMIDITY": "humidité",
"TEMPERATURE": "température", "TEMPERATURE": "température",

View File

@ -4,9 +4,14 @@
<Card> <Card>
<template #title>{{ $t('statistics.STATISTICS') }}</template> <template #title>{{ $t('statistics.STATISTICS') }}</template>
<template #content> <template #content>
<Statistics :user="authUser" :sports="sports" /> <Statistics
:class="{ 'stats-disabled': authUser.nb_workouts === 0 }"
:user="authUser"
:sports="sports"
/>
</template> </template>
</Card> </Card>
<NoWorkouts v-if="authUser.nb_workouts === 0"></NoWorkouts>
</div> </div>
</div> </div>
</template> </template>
@ -15,6 +20,7 @@
import { ComputedRef, computed, defineComponent } from 'vue' import { ComputedRef, computed, defineComponent } from 'vue'
import Card from '@/components/Common/Card.vue' import Card from '@/components/Common/Card.vue'
import NoWorkouts from '@/components/Common/NoWorkouts.vue'
import Statistics from '@/components/Statistics/index.vue' import Statistics from '@/components/Statistics/index.vue'
import { USER_STORE, SPORTS_STORE } from '@/store/constants' import { USER_STORE, SPORTS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import { ISport } from '@/types/sports'
@ -25,6 +31,7 @@
name: 'StatisticsView', name: 'StatisticsView',
components: { components: {
Card, Card,
NoWorkouts,
Statistics, Statistics,
}, },
setup() { setup() {
@ -49,10 +56,9 @@
width: 100%; width: 100%;
margin-bottom: 30px; margin-bottom: 30px;
.container { .container {
display: flex;
flex-direction: column;
width: 100%; width: 100%;
::v-deep(.card) {
width: 100%;
}
} }
} }
</style> </style>