From 4718315e4c1f2b1dd306d88618a2bcb9c9e43f6f Mon Sep 17 00:00:00 2001
From: Trirst <abeces968@gmail.com>
Date: Sat, 24 Jul 2021 01:08:26 +0700
Subject: [PATCH] Componentize the pagination bar

---
 src/components/ImageList.vue     | 39 ++++++++++----------------
 src/components/PaginationBar.vue | 48 ++++++++++++++++++++++++++++++++
 tailwind.config.js               |  1 +
 3 files changed, 64 insertions(+), 24 deletions(-)
 create mode 100644 src/components/PaginationBar.vue

diff --git a/src/components/ImageList.vue b/src/components/ImageList.vue
index 077d8dc..954a9cd 100644
--- a/src/components/ImageList.vue
+++ b/src/components/ImageList.vue
@@ -1,5 +1,10 @@
 <template>
   <section class="w-full">
+    <PaginationBar
+      :current-page="currentPage"
+      :last-page="lastPage"
+      @onPageChange="pageChange"
+    />
     <div class="w-full flex flex-row flex-wrap relative">
       <div
         v-for="(hash, index) in stateHashArray"
@@ -9,16 +14,11 @@
         <ImageItem :hash="hash" @checked="appendToDeleteArray"></ImageItem>
       </div>
     </div>
-    <div class="mx-auto max-w-max">
-      <button
-        v-for="(page, index) in pages"
-        :key="index"
-        class="mr-2"
-        @click="updatePage(page)"
-      >
-        {{ page }}
-      </button>
-    </div>
+    <PaginationBar
+      :current-page="currentPage"
+      :last-page="lastPage"
+      @onPageChange="pageChange"
+    />
     <button
       v-show="deleteArray.length"
       @click="deleteImages(deleteArray)"
@@ -31,10 +31,13 @@
 
 <script>
 import ImageItem from "@/components/ImageItem.vue";
+import PaginationBar from "@/components/PaginationBar.vue";
 import { mapState, mapActions } from "vuex";
+
 export default {
   components: {
     ImageItem,
+    PaginationBar,
   },
   data: () => {
     return {
@@ -44,26 +47,14 @@ export default {
     };
   },
   computed: {
-    // TODO: Rewrite this less confusingly if possible.
-    pages: function () {
-      return [
-        this.currentPage - 1 > 1 ? 1 : null,
-        this.currentPage - 1 > 2 ? "..." : null,
-        this.currentPage !== 1 ? this.currentPage - 1 : null,
-        this.currentPage,
-        this.currentPage !== this.lastPage ? this.currentPage + 1 : null,
-        this.lastPage - this.currentPage > 2 ? "..." : null,
-        this.lastPage - this.currentPage > 1 ? this.lastPage : null,
-      ].filter((element) => element !== null);
-    },
     ...mapState(["stateUser", "stateHashArray"]),
   },
   async created() {
-    this.updatePage(this.currentPage);
+    this.pageChange(this.currentPage);
     this.lastPage = Number(await this.getTotalPages());
   },
   methods: {
-    async updatePage(pageNumber) {
+    async pageChange(pageNumber) {
       if (pageNumber === "...") {
         let pageNumber = Number(prompt("Jump to page"));
         if (
diff --git a/src/components/PaginationBar.vue b/src/components/PaginationBar.vue
new file mode 100644
index 0000000..b026fd9
--- /dev/null
+++ b/src/components/PaginationBar.vue
@@ -0,0 +1,48 @@
+<template>
+  <div class="mx-auto max-w-max">
+    <button
+      v-for="(page, index) in pages"
+      :key="index"
+      class="mr-2 last:mr-0"
+      @click="$emit('onPageChange', page)"
+    >
+      {{ page }}
+    </button>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    currentPage: {
+      type: Number,
+      required: true,
+    },
+    lastPage: {
+      type: Number,
+      required: true,
+    },
+  },
+  computed: {
+    // TODO: Rewrite this less confusingly if possible.
+    // This returns an array that represents the pagination bar
+    // Demonstration:
+    // 1 ... 3 [4] 5 ... 12 (4 is the selected page)
+    // [1] 2 ... 12
+    // 1 2 [3] 4 ... 12
+    // The bar always shows the first and last pages, the selected page and 2 pages 
+    // that are offset by 1 to the selected page
+    pages: function () {
+      return [
+        this.currentPage - 1 > 1 ? 1 : null,
+        this.currentPage - 1 > 2 ? "..." : null,
+        this.currentPage !== 1 ? this.currentPage - 1 : null,
+        this.currentPage,
+        this.currentPage !== this.lastPage ? this.currentPage + 1 : null,
+        this.lastPage - this.currentPage > 2 ? "..." : null,
+        this.lastPage - this.currentPage > 1 ? this.lastPage : null,
+      ].filter((element) => element !== null);
+    },
+  },
+};
+</script>
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
index 90d0d37..2e9fb81 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -10,6 +10,7 @@ module.exports = {
   variants: {
     extend: {
       opacity: ['disabled'],
+      margin: ['last'],
     },
   },
   plugins: [],
-- 
GitLab