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" 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"> <div class="-mt-px w-0 flex-1 flex">
<a <NuxtLink
v-if="prevPageToken"
:to="{ name: 'index', query: { pageToken: prevPageToken } }"
href="#" 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" 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 Previous
</a> </NuxtLink>
</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>
</div> </div>
<div class="-mt-px w-0 flex-1 flex justify-end"> <div class="-mt-px w-0 flex-1 flex justify-end">
<a <NuxtLink
v-if="nextPageToken"
:to="{ name: 'index', query: { pageToken: nextPageToken } }"
href="#" 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" 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 Next
</a> </NuxtLink>
</div> </div>
</nav> </nav>
</template> </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> <template>
<div <div>
id="videolist"
class="max-w-2xl mx-auto py-8 px-4 sm:px-6 lg:max-w-7xl lg:px-8"
>
<h2 class="sr-only">Videos</h2> <h2 class="sr-only">Videos</h2>
<div <div
@ -17,34 +14,18 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
const maxResults: number = 2
export default Vue.extend({ export default Vue.extend({
name: 'VideoList', name: 'VideoList',
data(): { props: {
hasError: boolean videos: {
videos: [] type: Array,
} { default: () => {
return { return []
hasError: false, },
videos: [], 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> </script>

View file

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

View file

@ -6,8 +6,17 @@
<main> <main>
<IndexHero /> <IndexHero />
<div class="bg-gray-200 pb-12"> <div class="bg-gray-200 pb-12">
<VideosList /> <div class="max-w-2xl mx-auto py-8 px-4 sm:px-6 lg:max-w-7xl lg:px-8">
<SimplePagination /> <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> </div>
</main> </main>
</div> </div>
@ -15,8 +24,48 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
const maxResults: number = 12
export default Vue.extend({ export default Vue.extend({
name: 'IndexPage', 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> </script>