summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2022-10-04 22:31:35 +0200
committerSanto Cariotti <santo@dcariotti.me>2022-10-04 22:31:35 +0200
commit36b5f74414413e7270d47f52df387697698aeeaf (patch)
tree050fc93827ca595a198bb2618dd817eeac845423
parent8806bb5f857502eec2ad9132757458d714fff442 (diff)
Add pagination
-rw-r--r--components/ModelForm.vue2
-rw-r--r--components/Pagination.vue35
-rw-r--r--pages/index.vue16
-rw-r--r--pages/search.vue14
-rw-r--r--pages/user/_id.vue19
-rw-r--r--store/users.js6
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",
},