FitTrackee/fittrackee_client/src/components/Common/Pagination.vue

128 lines
3.1 KiB
Vue
Raw Normal View History

2021-10-31 11:21:21 +01:00
<template>
<nav class="pagination-center" aria-label="navigation">
<ul class="pagination">
<li class="page-prev" :class="{ disabled: !pagination.has_prev }">
<router-link
class="page-link"
:to="{ path, query: getQuery(pagination.page, -1) }"
:event="pagination.has_prev ? 'click' : ''"
:disabled="!pagination.has_prev"
>
<i class="fa fa-chevron-left" aria-hidden="true" />
2021-10-31 11:21:21 +01:00
{{ $t('api.PAGINATION.PREVIOUS') }}
</router-link>
</li>
<li
v-for="page in rangePagination(pagination.pages, pagination.page)"
2021-10-31 11:21:21 +01:00
:key="page"
class="page"
:class="{ active: page === pagination.page }"
>
<span v-if="page === '...'"> ... </span>
<router-link
v-else
class="page-link"
:to="{ path, query: getQuery(+page) }"
>
2021-10-31 11:21:21 +01:00
{{ page }}
</router-link>
</li>
<li class="page-next" :class="{ disabled: !pagination.has_next }">
<router-link
class="page-link"
:to="{ path, query: getQuery(pagination.page, 1) }"
:event="pagination.has_next ? 'click' : ''"
:disabled="!pagination.has_next"
>
{{ $t('api.PAGINATION.NEXT') }}
<i class="fa fa-chevron-right" aria-hidden="true" />
2021-10-31 11:21:21 +01:00
</router-link>
</li>
</ul>
</nav>
</template>
<script setup lang="ts">
import { toRefs } from 'vue'
2021-10-31 11:21:21 +01:00
import { IPagination } from '@/types/api'
import { TWorkoutsPayload } from '@/types/workouts'
import { rangePagination } from '@/utils/api'
2021-10-31 11:21:21 +01:00
interface Props {
pagination: IPagination
path: string
query: TWorkoutsPayload
}
const props = defineProps<Props>()
const { pagination, path, query } = toRefs(props)
function getQuery(page: number, cursor?: number): TWorkoutsPayload {
const newQuery = Object.assign({}, query.value)
newQuery.page = cursor ? page + cursor : page
return newQuery
}
2021-10-31 11:21:21 +01:00
</script>
<style lang="scss" scoped>
2021-11-29 11:23:21 +01:00
@import '~@/scss/vars.scss';
2021-10-31 11:21:21 +01:00
.pagination-center {
display: flex;
justify-content: center;
font-size: 0.9em;
.pagination {
display: flex;
padding-left: 0;
list-style: none;
border-radius: 0.25rem;
.page-prev,
.page-next,
.page {
border: solid 1px var(--card-border-color);
padding: $default-padding $default-padding * 1.5;
&.active {
font-weight: bold;
}
&.disabled {
cursor: default;
a {
color: var(--disabled-color);
}
}
}
.page {
margin-left: -1px;
}
.page-prev {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.page-next {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
margin-left: -1px;
}
.fa {
font-size: 0.8em;
padding: 0 $default-padding * 0.5;
}
}
@media screen and (max-width: $medium-limit) {
.pagination {
.page {
display: none;
}
}
2021-10-31 11:21:21 +01:00
}
}
</style>