Pagination

This commit is contained in:
Jai A 2020-09-06 22:29:35 -07:00
parent ce8a0cab2a
commit fc6246c5cb
4 changed files with 97 additions and 19 deletions

View File

@ -1,5 +1,3 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');
:root { :root {
/** /**
* Colors * Colors

View File

@ -3,7 +3,7 @@
<aside> <aside>
<div class="logo-wrapper"> <div class="logo-wrapper">
<img class="logo" src="~/assets/images/logo.svg" /> <img class="logo" src="~/assets/images/logo.svg" />
<h1>modrinth</h1> <span class="name">modrinth</span>
</div> </div>
<nav> <nav>
<section class="links"> <section class="links">
@ -157,8 +157,6 @@
</template> </template>
<style lang="scss"> <style lang="scss">
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@600&display=swap');
.layout { .layout {
display: flex; display: flex;
min-height: 100vh; min-height: 100vh;
@ -186,9 +184,10 @@
width: auto; width: auto;
} }
h1 { .name {
margin-left: 10px; font-family: 'Montserrat Alternates';
font-family: 'Montserrat', sans-serif; margin-left: 0.4rem;
font-size: 1.3rem;
} }
} }

View File

@ -24,7 +24,19 @@ export default {
content: process.env.npm_package_description || '', content: process.env.npm_package_description || '',
}, },
], ],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }], link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{
rel: 'stylesheet',
href:
'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap',
},
{
rel: 'stylesheet',
href:
'https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@600&display=swap',
},
],
script: [ script: [
{ {
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js', src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',

View File

@ -10,7 +10,7 @@
type="search" type="search"
name="search" name="search"
placeholder="Search mods" placeholder="Search mods"
@input="onSearchChange" @input="onSearchChange(true)"
/> />
<svg <svg
viewBox="0 0 24 24" viewBox="0 0 24 24"
@ -24,29 +24,51 @@
<line x1="21" y1="21" x2="16.65" y2="16.65" /> <line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg> </svg>
</div> </div>
<div class="pagination column-grow-1 columns paginates"> <div
v-if="pages.length > 1"
class="pagination column-grow-1 columns paginates"
>
<svg <svg
:class="{ 'disabled-paginate': currentPage === 1 }"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
stroke-width="2" stroke-width="2"
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
@click="currentPage !== 1 ? switchPage(currentPage - 1) : null"
> >
<polyline points="15 18 9 12 15 6"></polyline> <polyline points="15 18 9 12 15 6"></polyline>
</svg> </svg>
<p>1</p> <p
<p>2</p> v-for="(item, index) in pages"
<p>3</p> :key="'page-' + item"
<p>...</p> :class="{
<p>10</p> 'active-page-number': currentPage !== item,
}"
@click="currentPage !== item ? switchPage(item) : null"
>
<span v-if="pages[index - 1] + 1 !== item && item !== 1">...</span>
<span :class="{ 'disabled-page-number': currentPage === item }">{{
item
}}</span>
</p>
<svg <svg
:class="{
'disabled-paginate': currentPage === pages[pages.length - 1],
}"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
stroke-width="2" stroke-width="2"
stroke-linecap="round" stroke-linecap="round"
stroke-linejoin="round" stroke-linejoin="round"
@click="
currentPage !== pages[pages.length - 1]
? switchPage(currentPage + 1)
: null
"
> >
<polyline points="9 18 15 12 9 6"></polyline> <polyline points="9 18 15 12 9 6"></polyline>
</svg> </svg>
@ -304,6 +326,8 @@ export default {
query: '', query: '',
filters: [], filters: [],
results: [], results: [],
pages: [],
currentPage: 1,
} }
}, },
async created() { async created() {
@ -322,9 +346,16 @@ export default {
this.filters.push(element.id) this.filters.push(element.id)
} }
await this.onSearchChange() await this.onSearchChange(true)
}, },
async onSearchChange() { async switchPage(pageNumber) {
this.currentPage = pageNumber
await this.onSearchChange(false)
},
async onSearchChange(resetPageNumber) {
if (resetPageNumber) this.currentPage = 1
const config = { const config = {
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
@ -349,6 +380,10 @@ export default {
params.push(`facets=${JSON.stringify(facets)}`) params.push(`facets=${JSON.stringify(facets)}`)
} }
if (this.currentPage !== 1) {
params.push(`offset=${(this.currentPage - 1) * 10}`)
}
if (params.length > 0) { if (params.length > 0) {
for (let i = 0; i < params.length; i++) { for (let i = 0; i < params.length; i++) {
url += i === 0 ? `?${params[i]}` : `&${params[i]}` url += i === 0 ? `?${params[i]}` : `&${params[i]}`
@ -356,9 +391,27 @@ export default {
} }
const res = await axios.get(url, config) const res = await axios.get(url, config)
this.results = res.data.hits this.results = res.data.hits
const pageAmount = Math.ceil(res.data.nb_hits / res.data.limit)
if (pageAmount > 4) {
if (this.currentPage > 4) {
this.pages = [
1,
this.currentPage - 1,
this.currentPage,
this.currentPage + 1,
pageAmount,
]
} else {
this.pages = [1, 2, 3, 4, pageAmount]
}
} else {
this.pages = Array.from({ length: pageAmount }, (_, i) => i + 1)
}
} catch (err) { } catch (err) {
// eslint-disable-next-line no-console
console.error(err) console.error(err)
} }
}, },
@ -446,4 +499,20 @@ export default {
border-left: 4px solid var(--color-brand); border-left: 4px solid var(--color-brand);
} }
} }
.disabled-paginate {
cursor: default;
color: var(--color-grey-3);
}
.active-page-number {
cursor: pointer;
}
.disabled-page-number {
cursor: default;
padding: 2px 3px;
border-radius: 3px;
background-color: var(--color-grey-3);
}
</style> </style>