1
0
Fork 0

feat: pagination

This commit is contained in:
Ava Gaiety Wroten 2021-12-31 12:05:48 -06:00
parent 95f59c3faf
commit 19f86d5b89
4 changed files with 95 additions and 79 deletions

View file

@ -3,65 +3,47 @@
class="border-t border-gray-200 flex items-center justify-between max-w-2xl mx-auto p-4 sm:px-6 lg:max-w-7xl"
>
<div class="-mt-px w-0 flex-1 flex">
<a
<NuxtLink
v-if="prevPageToken"
:to="{ name: 'index', query: { pageToken: prevPageToken } }"
href="#"
class="border-t-2 border-transparent pt-4 pr-1 inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300"
>
Previous
</a>
</div>
<div class="hidden md:-mt-px md:flex">
<a
href="#"
class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
1
</a>
<!-- Current: "border-pink-500 text-pink-600", Default: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300" -->
<a
href="#"
class="border-brandlight text-brandlight border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
aria-current="page"
>
2
</a>
<a
href="#"
class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
3
</a>
<span
class="border-transparent text-gray-500 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
...
</span>
<a
href="#"
class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
8
</a>
<a
href="#"
class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
9
</a>
<a
href="#"
class="border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 border-t-2 pt-4 px-4 inline-flex items-center text-sm font-medium"
>
10
</a>
</NuxtLink>
</div>
<div class="-mt-px w-0 flex-1 flex justify-end">
<a
<NuxtLink
v-if="nextPageToken"
:to="{ name: 'index', query: { pageToken: nextPageToken } }"
href="#"
class="border-t-2 border-transparent pt-4 pl-1 inline-flex items-center text-sm font-medium text-gray-500 hover:text-gray-700 hover:border-gray-300"
>
Next
</a>
</NuxtLink>
</div>
</nav>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'SimplePagination',
props: {
nextPageToken: {
type: String,
default: () => {
return ''
},
},
prevPageToken: {
type: String,
default: () => {
return ''
},
},
},
})
</script>

View file

@ -1,8 +1,5 @@
<template>
<div
id="videolist"
class="max-w-2xl mx-auto py-8 px-4 sm:px-6 lg:max-w-7xl lg:px-8"
>
<div>
<h2 class="sr-only">Videos</h2>
<div
@ -17,34 +14,18 @@
<script lang="ts">
import Vue from 'vue'
const maxResults: number = 2
export default Vue.extend({
name: 'VideoList',
data(): {
hasError: boolean
videos: []
} {
return {
hasError: false,
videos: [],
}
props: {
videos: {
type: Array,
default: () => {
return []
},
required: true,
},
},
async fetch() {
try {
const response = await fetch(
`https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&maxResults=${maxResults}&playlistId=${process.env.YOUTUBE_UPLOADS_PLAYLIST_ID}&key=${process.env.YOUTUBE_API_KEY}`
)
const json = await response.json()
this.videos = json.items
} catch (error: any) {
this.hasError = true
throw new Error(error)
}
},
fetchOnServer: true,
})
</script>

View file

@ -112,6 +112,10 @@ export default {
],
},
router: {
routes: [{ path: '/:pageToken', props: true }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],

View file

@ -6,8 +6,17 @@
<main>
<IndexHero />
<div class="bg-gray-200 pb-12">
<VideosList />
<SimplePagination />
<div class="max-w-2xl mx-auto py-8 px-4 sm:px-6 lg:max-w-7xl lg:px-8">
<p v-if="$fetchState.pending">Fetching videos...</p>
<p v-else-if="$fetchState.error">An error occurred :(</p>
<div v-else id="videolist">
<VideosList :videos="videos" />
<SimplePagination
:prev-page-token="prevPageToken"
:next-page-token="nextPageToken"
/>
</div>
</div>
</div>
</main>
</div>
@ -15,8 +24,48 @@
<script lang="ts">
import Vue from 'vue'
const maxResults: number = 12
export default Vue.extend({
name: 'IndexPage',
data(): {
videos: []
prevPageToken: string
nextPageToken: string
} {
return {
videos: [],
prevPageToken: '',
nextPageToken: '',
}
},
async fetch() {
try {
let requestUrl =
'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails'
requestUrl += `&maxResults=${maxResults}`
requestUrl += `&playlistId=${process.env.NUXT_ENV_YOUTUBE_UPLOADS_PLAYLIST_ID}`
requestUrl += `&key=${process.env.NUXT_ENV_YOUTUBE_API_KEY}`
if (this.$route.query.pageToken)
requestUrl += `&pageToken=${this.$route.query.pageToken}`
const response = await fetch(requestUrl)
const json = await response.json()
this.prevPageToken = json.prevPageToken
this.nextPageToken = json.nextPageToken
this.videos = json.items
} catch (error: any) {
throw new Error(error)
}
},
watch: {
'$route.query': '$fetch',
},
fetchOnServer: true,
})
</script>