Client - get workouts ordered by distance, duration or average speed
This commit is contained in:
parent
05b22e6f72
commit
e8350abf55
@ -9,7 +9,7 @@
|
||||
@change="onSelectUpdate"
|
||||
>
|
||||
<option v-for="order in order_by" :value="order" :key="order">
|
||||
{{ $t(`${message}.${order}`) }}
|
||||
{{ $t(`${message}.${order.toUpperCase()}`) }}
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
|
@ -157,9 +157,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, ComputedRef, defineComponent, PropType } from 'vue'
|
||||
import { computed, ComputedRef, defineComponent, PropType, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { LocationQuery, useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
@ -180,12 +180,13 @@
|
||||
emits: ['filter'],
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const translatedSports: ComputedRef<ISport[]> = computed(() =>
|
||||
translateSports(props.sports, t)
|
||||
)
|
||||
const params: Record<string, string> = {}
|
||||
let params: LocationQuery = Object.assign({}, route.query)
|
||||
|
||||
function handleFilterChange(event: Event & { target: HTMLInputElement }) {
|
||||
if (event.target.value === '') {
|
||||
@ -199,6 +200,13 @@
|
||||
router.push({ path: '/workouts', query: params })
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.query,
|
||||
(newQuery) => {
|
||||
params = Object.assign({}, newQuery)
|
||||
}
|
||||
)
|
||||
|
||||
return { translatedSports, onFilter, handleFilterChange }
|
||||
},
|
||||
})
|
||||
|
@ -1,6 +1,13 @@
|
||||
<template>
|
||||
<div class="workouts-list">
|
||||
<div class="box" :class="{ 'empty-table': workouts.length === 0 }">
|
||||
<FilterSelects
|
||||
:sort="sortList"
|
||||
:order_by="orderByList"
|
||||
:query="query"
|
||||
message="workouts"
|
||||
@updateSelect="reloadWorkouts"
|
||||
/>
|
||||
<div class="workouts-table responsive-table">
|
||||
<table>
|
||||
<thead>
|
||||
@ -103,26 +110,28 @@
|
||||
PropType,
|
||||
computed,
|
||||
defineComponent,
|
||||
ref,
|
||||
watch,
|
||||
capitalize,
|
||||
onBeforeMount,
|
||||
} from 'vue'
|
||||
import { LocationQuery, useRoute } from 'vue-router'
|
||||
import { LocationQuery, useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import FilterSelects from '@/components/Common/FilterSelects.vue'
|
||||
import StaticMap from '@/components/Common/StaticMap.vue'
|
||||
import NoWorkouts from '@/components/Workouts/NoWorkouts.vue'
|
||||
import { WORKOUTS_STORE } from '@/store/constants'
|
||||
import { ITranslatedSport } from '@/types/sports'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import { IWorkout, TWorkoutsPayload } from '@/types/workouts'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getQuery, sortList, workoutsPayloadKeys } from '@/utils/api'
|
||||
import { getDateWithTZ } from '@/utils/dates'
|
||||
import { defaultOrder } from '@/utils/workouts'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'WorkoutsList',
|
||||
components: {
|
||||
FilterSelects,
|
||||
NoWorkouts,
|
||||
StaticMap,
|
||||
},
|
||||
@ -138,39 +147,70 @@
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const orderByList: string[] = [
|
||||
'ave_speed',
|
||||
'distance',
|
||||
'duration',
|
||||
'workout_date',
|
||||
]
|
||||
const workouts: ComputedRef<IWorkout[]> = computed(
|
||||
() => store.getters[WORKOUTS_STORE.GETTERS.USER_WORKOUTS]
|
||||
)
|
||||
const per_page = 10
|
||||
const page = ref(1)
|
||||
let query: TWorkoutsPayload = getWorkoutsQuery(route.query)
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadWorkouts(route.query)
|
||||
loadWorkouts(query)
|
||||
})
|
||||
|
||||
function loadWorkouts(newQuery: LocationQuery) {
|
||||
page.value = 1
|
||||
store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, {
|
||||
page: page.value,
|
||||
per_page,
|
||||
...defaultOrder,
|
||||
...newQuery,
|
||||
function loadWorkouts(payload: TWorkoutsPayload) {
|
||||
store.dispatch(WORKOUTS_STORE.ACTIONS.GET_USER_WORKOUTS, payload)
|
||||
}
|
||||
function reloadWorkouts(queryParam: string, queryValue: string) {
|
||||
const newQuery: LocationQuery = Object.assign({}, route.query)
|
||||
newQuery[queryParam] = queryValue
|
||||
if (queryParam === 'per_page') {
|
||||
newQuery['page'] = '1'
|
||||
}
|
||||
query = getWorkoutsQuery(newQuery)
|
||||
router.push({ path: '/workouts', query })
|
||||
}
|
||||
|
||||
function getWorkoutsQuery(newQuery: LocationQuery): TWorkoutsPayload {
|
||||
query = getQuery(newQuery, orderByList, defaultOrder.order_by, {
|
||||
defaultSort: defaultOrder.order,
|
||||
query,
|
||||
})
|
||||
Object.keys(newQuery)
|
||||
.filter((k) => workoutsPayloadKeys.includes(k))
|
||||
.map((k) => {
|
||||
if (typeof newQuery[k] === 'string') {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
query[k] = newQuery[k]
|
||||
}
|
||||
})
|
||||
return query
|
||||
}
|
||||
|
||||
watch(
|
||||
() => route.query,
|
||||
async (newQuery) => {
|
||||
loadWorkouts(newQuery)
|
||||
query = getWorkoutsQuery(newQuery)
|
||||
loadWorkouts(query)
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
query,
|
||||
orderByList,
|
||||
sortList,
|
||||
workouts,
|
||||
capitalize,
|
||||
format,
|
||||
getDateWithTZ,
|
||||
reloadWorkouts,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
@ -36,10 +36,10 @@
|
||||
},
|
||||
"SELECTS": {
|
||||
"ORDER_BY": {
|
||||
"admin": "admin status",
|
||||
"created_at": "registration date",
|
||||
"username": "username",
|
||||
"workouts_count": "workout count"
|
||||
"ADMIN": "admin status",
|
||||
"CREATED_AT": "registration date",
|
||||
"USERNAME": "username",
|
||||
"WORKOUTS_COUNT": "workout count"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,10 +36,10 @@
|
||||
},
|
||||
"SELECTS": {
|
||||
"ORDER_BY": {
|
||||
"admin": "status administrateur",
|
||||
"created_at": "date d'inscription",
|
||||
"username": "nom d'utilisateur",
|
||||
"workouts_count": "nombre de séances"
|
||||
"ADMIN": "status administrateur",
|
||||
"CREATED_AT": "date d'inscription",
|
||||
"USERNAME": "nom d'utilisateur",
|
||||
"WORKOUTS_COUNT": "nombre de séances"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { TWorkoutsPayload } from '@/types/workouts'
|
||||
|
||||
export interface IPagination {
|
||||
has_next: boolean
|
||||
has_prev: boolean
|
||||
|
@ -48,3 +48,17 @@ export const getQuery = (
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
export const workoutsPayloadKeys = [
|
||||
'from',
|
||||
'to',
|
||||
'ave_speed_from',
|
||||
'ave_speed_to',
|
||||
'max_speed_from',
|
||||
'max_speed_to',
|
||||
'distance_from',
|
||||
'distance_to',
|
||||
'duration_from',
|
||||
'duration_to',
|
||||
'sport_id',
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user