diff options
author | Santo Cariotti <santo@dcariotti.me> | 2022-10-04 22:31:35 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2022-10-04 22:31:35 +0200 |
commit | 36b5f74414413e7270d47f52df387697698aeeaf (patch) | |
tree | 050fc93827ca595a198bb2618dd817eeac845423 | |
parent | 8806bb5f857502eec2ad9132757458d714fff442 (diff) |
Add pagination
-rw-r--r-- | components/ModelForm.vue | 2 | ||||
-rw-r--r-- | components/Pagination.vue | 35 | ||||
-rw-r--r-- | pages/index.vue | 16 | ||||
-rw-r--r-- | pages/search.vue | 14 | ||||
-rw-r--r-- | pages/user/_id.vue | 19 | ||||
-rw-r--r-- | store/users.js | 6 |
6 files changed, 83 insertions, 9 deletions
diff --git a/components/ModelForm.vue b/components/ModelForm.vue index d59a5ae..f7b622c 100644 --- a/components/ModelForm.vue +++ b/components/ModelForm.vue @@ -248,6 +248,8 @@ export default { this.$toast.error(response.data.error); } }); + } else { + this.$toast.error("Fill all the required fields"); } event.preventDefault(); }, diff --git a/components/Pagination.vue b/components/Pagination.vue new file mode 100644 index 0000000..053d7cf --- /dev/null +++ b/components/Pagination.vue @@ -0,0 +1,35 @@ +<template lang="pug"> + .mt-10.text-center + nav.isolate.inline-flex.-space-x-px.rounded-md.shadow-sm(aria-label="Pagination") + a.relative.inline-flex.items-center.rounded-l-md.border.border-gray-300.bg-white.px-2.py-2.text-sm.font-medium.text-gray-500( + :href="(page == 0) ? '#' : '/?page='+incrPage(-1)" + :class="{'hover:bg-gray-50 focus:z-20': true, 'cursor-not-allowed opacity-20': page < 1}" + ) + span.sr-only Previous + svg.h-5.w-5(xmlns="http://www.w3.org/2000/svg", viewbox="0 0 20 20", fill="currentColor", aria-hidden="true") + path(fill-rule="evenodd", d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z", clip-rule="evenodd") + a.relative.z-10.inline-flex.items-center.border.border-gray-300.px-4.py-2.text-sm.font-medium.text-gray-500.bg-white( + :href="'/?page='+(i-1)" aria-current="page" + :class="{'focus:z-20': true, 'bg-green-50 text-green-600 border-green-500': page == (i-1)}" + v-for="i in pages" + ) {{ i-1 }} + a.relative.inline-flex.items-center.rounded-r-md.border.border-gray-300.bg-white.px-2.py-2.text-sm.font-medium.text-gray-500( + :href="(page == (pages-1)) ? '#' : '/?page='+incrPage(1)" + :class="{'hover:bg-gray-50 focus:z-20': true, 'cursor-not-allowed opacity-20': page == (pages-1)}" + ) + span.sr-only Next + svg.h-5.w-5(xmlns="http://www.w3.org/2000/svg", viewbox="0 0 20 20", fill="currentColor", aria-hidden="true") + path(fill-rule="evenodd", d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z", clip-rule="evenodd") + </template> + +<script> +export default { + name: "Pagination", + props: ["page", "pages"], + methods: { + incrPage(value) { + return Number(this.page) + value; + }, + }, +}; +</script> diff --git a/pages/index.vue b/pages/index.vue index 27c157a..5884e7c 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -19,11 +19,13 @@ :key="model.id" :model="model" ) + pagination(:page="page" :pages="pages" v-if="count") </template> <script> import ModelLoading from "@/components/ModelLoading.vue"; import ModelBoxCard from "@/components/ModelBoxCard.vue"; +import Pagination from "@/components/Pagination.vue"; import { mapGetters } from "vuex"; @@ -36,14 +38,24 @@ export default { components: { "model-loading": ModelLoading, "model-box-card": ModelBoxCard, + pagination: Pagination, + }, + data() { + return { + page: 0, + pages: 0, + }; }, computed: { ...mapGetters(["isLoading"]), ...mapGetters("auth", ["isLogged"]), - ...mapGetters("models", ["models"]), + ...mapGetters("models", ["models", "count"]), }, created() { - this.$store.dispatch("models/getModels"); + this.page = this.$route.query.page ?? 0; + this.$store.dispatch("models/getModels", this.page).then(() => { + this.pages = Math.ceil(this.count / 20); + }); }, }; </script> diff --git a/pages/search.vue b/pages/search.vue index 1c09e3b..6f448af 100644 --- a/pages/search.vue +++ b/pages/search.vue @@ -21,11 +21,13 @@ :key="model.id" :model="model" ) + pagination(:page="page" :pages="pages" v-if="count") </template> <script> import ModelLoading from "@/components/ModelLoading.vue"; import ModelBoxCard from "@/components/ModelBoxCard.vue"; +import Pagination from "@/components/Pagination.vue"; import { mapGetters } from "vuex"; @@ -40,20 +42,28 @@ export default { data() { return { q: "", + page: 0, + pages: 0, }; }, components: { "model-loading": ModelLoading, "model-box-card": ModelBoxCard, + pagination: Pagination, }, computed: { ...mapGetters(["isLoading"]), ...mapGetters("auth", ["isLogged"]), - ...mapGetters("models", ["models"]), + ...mapGetters("models", ["models", "count"]), }, created() { this.q = this.$route.query["q"]; - this.$store.dispatch("models/filter", { q: this.q }); + this.page = this.$route.query.page ?? 0; + this.$store + .dispatch("models/filter", { q: this.q, page: this.page }) + .then(() => { + this.pages = Math.ceil(this.count / 20); + }); }, }; </script> diff --git a/pages/user/_id.vue b/pages/user/_id.vue index a43a7c8..797f2c0 100644 --- a/pages/user/_id.vue +++ b/pages/user/_id.vue @@ -19,6 +19,7 @@ :key="model.id" :model="model" ) + pagination(:page="page" :pages="pages" v-if="count") h4.text-lg(v-else class="dark:text-white") No models found </template> @@ -28,6 +29,7 @@ import UserAvatar from "@/components/UserAvatar.vue"; import FilePreview from "@/components/FilePreview.vue"; import ModelLoading from "@/components/ModelLoading.vue"; import ModelBoxCard from "@/components/ModelBoxCard.vue"; +import Pagination from "@/components/Pagination.vue"; import { mapGetters } from "vuex"; @@ -39,6 +41,9 @@ export default { id: 0, user: {}, models: [], + count: 0, + page: 0, + pages: 0, }; }, head() { @@ -51,12 +56,14 @@ export default { "file-preview": FilePreview, "model-loading": ModelLoading, "model-box-card": ModelBoxCard, + pagination: Pagination, }, computed: { ...mapGetters(["isLoading"]), }, created() { this.id = this.$route.params.id; + this.page = this.$route.query.page ?? 0; this.$store.dispatch("users/findById", this.id).then((response) => { if (response.status != 200) { @@ -66,9 +73,15 @@ export default { } }); - this.$store.dispatch("users/findModels", this.id).then((response) => { - if (response.status == 200) this.models = response.data.results; - }); + this.$store + .dispatch("users/findModels", { id: this.id, page: this.page }) + .then((response) => { + if (response.status == 200) { + this.models = response.data.results; + this.count = response.data.count; + this.pages = Math.ceil(this.count / 20); + } + }); }, }; </script> diff --git a/store/users.js b/store/users.js index cf1ca86..90e4dad 100644 --- a/store/users.js +++ b/store/users.js @@ -39,12 +39,14 @@ export const actions = { return res; }, // Search user models - async findModels({ commit }, id) { + async findModels({ commit }, data) { commit("loadingStatus", true, { root: true }); let res = { status: 0, data: null }; let api = this.$config.api; + const id = data.id; + const page = data.page ? data.page : 0; - await fetch(`${api}/v1/users/${id}/models`, { + await fetch(`${api}/v1/users/${id}/models?page=${page}`, { headers: { "Content-Type": "application/json", }, |