Skip to content

Commit

Permalink
fix: prerender news pages as routes with pagination
Browse files Browse the repository at this point in the history
Signed-off-by: nurRiyad <[email protected]>
  • Loading branch information
nurRiyad authored and romangg committed Aug 16, 2024
1 parent f6f4fff commit 7823da8
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 85 deletions.
92 changes: 92 additions & 0 deletions components/news-list.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<template>
<section class="py-12 px-4 mx-auto max-w-screen-xl body-font">
<div class="flex flex-col text-center w-full mb-14">
<h1 class="text-3xl font-medium mb-4">
News and Announcements
</h1>
<p class="lg:w-2/3 mx-auto leading-relaxed text-gray-700 dark:text-gray-400">
Articles about development and organization of the Manjaro project
</p>
</div>

<div class="mx-auto max-w-[400px] md:max-w-[820px] xl:max-w-max font-[sans-serif] grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
<NuxtLink
v-for="item of paginatedData"
:key="item.id"
:href="item._path!"
class="flex flex-col rounded overflow-hidden border dark:border-gray-700 transform hover:scale-[1.02] transition-transform duration-300"
>
<div>
<NuxtImg
:src="getImagePath(item._path!, item.image!)"
alt="News article header picture"
class="w-full h-52 object-cover"
width="500px"
/>
</div>
<div class="flex flex-col justify-start p-4 lg:p-5 h-full">
<span class="text-sm block text-gray-400 dark:text-gray-500 mb-2 capitalize">
{{ useTimeAgo(item.date).value }} | {{ getAuthors(item.authors)[0].name }}
</span>
<h3 class="text-lg font-bold pb-3">
{{ item.title }}
</h3>
<p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-2 ">
{{ item.description }}
</p>
</div>
</NuxtLink>
</div>

<PaginationItem
v-model="currentPage"
:total-item="data?.length"
:item-per-page="itemPerPage"
class="pt-14"
/>
</section>
</template>
<script setup lang="ts">
import { useTimeAgo } from '@vueuse/core'
useHead({
title: 'News',
})
useServerSeoMeta({
ogTitle: 'Manjaro News',
description: 'Articles about development and organization of the Manjaro project.',
})
const getImagePath = (path: string, file: string) => {
return path + '/' + file
}
const { data } = await useAsyncData('news-items-list', () =>
queryContent('/news')
.sort({ date: -1 })
.find(),
)
const currentPage = ref(1)
const itemPerPage = 9
const totalBlogs = data.value?.length || 1
const totalPage = Math.ceil(totalBlogs / itemPerPage)
const route = useRoute()
watch(() => route.params.page, async (n) => {
if (typeof n === 'string') {
const pageNo = parseInt(n)
if (pageNo === 1) await navigateTo('/news')
if (pageNo && pageNo > 0 && pageNo <= totalPage) {
currentPage.value = pageNo
}
else await navigateTo('/news')
}
}, { immediate: true })
const paginatedData = computed(() => {
const startIndex = itemPerPage * (currentPage.value - 1)
return data.value?.slice(startIndex, startIndex + itemPerPage)
})
</script>
12 changes: 3 additions & 9 deletions components/pagination-item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
class="flex p-5 justify-center"
>
<div class="join">
<button
<NuxtLink
v-for="page in pageNumbers"
:key="page"
:class="{ 'btn-primary': page === currentPage, 'btn-disabled': page === '...' }"
:to="page === 1 ? '/news': `/news/page/${page}`"
class="join-item btn no-animation"
@click="handlePageChange(page)"
>
{{ page }}
</button>
</NuxtLink>
</div>
</div>
</template>
Expand Down Expand Up @@ -40,10 +40,4 @@ const pageNumbers = computed(() => {
return Array.from({ length: ttlPage.value }, (_, i) => i + 1)
}
})
const handlePageChange = (page: number | string) => {
if (typeof page === 'number') {
currentPage.value = page
}
}
</script>
1 change: 1 addition & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default defineNuxtConfig({
dataValue: 'theme', // for daisyUI
},
routeRules: {
'/news/page/1': { redirect: { to: '/news' } },
'/products/download': { redirect: { to: '/products', statusCode: 302 } },
'/download': { redirect: { to: '/products', statusCode: 302 } },
},
Expand Down
77 changes: 1 addition & 76 deletions pages/news/index.vue
Original file line number Diff line number Diff line change
@@ -1,78 +1,3 @@
<template>
<section class="py-12 px-4 mx-auto max-w-screen-xl body-font">
<div class="flex flex-col text-center w-full mb-14">
<h1 class="text-3xl font-medium mb-4">
News and Announcements
</h1>
<p class="lg:w-2/3 mx-auto leading-relaxed text-gray-700 dark:text-gray-400">
Articles about development and organization of the Manjaro project
</p>
</div>

<div class="mx-auto max-w-[400px] md:max-w-[820px] xl:max-w-max font-[sans-serif] grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
<NuxtLink
v-for="item of paginatedData"
:key="item.id"
:href="item._path!"
class="flex flex-col rounded overflow-hidden border dark:border-gray-700 transform hover:scale-[1.02] transition-transform duration-300"
>
<div>
<NuxtImg
:src="getImagePath(item._path!, item.image!)"
alt="News article header picture"
class="w-full h-52 object-cover"
width="500px"
/>
</div>
<div class="flex flex-col justify-start p-4 lg:p-5 h-full">
<span class="text-sm block text-gray-400 dark:text-gray-500 mb-2 capitalize">
{{ useTimeAgo(item.date).value }} | {{ getAuthors(item.authors)[0].name }}
</span>
<h3 class="text-lg font-bold pb-3">
{{ item.title }}
</h3>
<p class="text-gray-600 dark:text-gray-300 text-sm line-clamp-2 ">
{{ item.description }}
</p>
</div>
</NuxtLink>
</div>

<PaginationItem
v-model="currentPage"
:total-item="data?.length"
:item-per-page="itemPerPage"
class="pt-14"
/>
</section>
<NewsList />
</template>
<script setup lang="ts">
import { useTimeAgo } from '@vueuse/core'
useHead({
title: 'News',
})
useServerSeoMeta({
ogTitle: 'Manjaro News',
description: 'Articles about development and organization of the Manjaro project.',
})
const getImagePath = (path: string, file: string) => {
return path + '/' + file
}
const { data } = await useAsyncData('news-items-list', () =>
queryContent('/news')
.sort({ date: -1 })
.find(),
)
const currentPage = ref(1)
const itemPerPage = 9
const paginatedData = computed(() => {
const startIndex = itemPerPage * (currentPage.value - 1)
return data.value?.slice(startIndex, startIndex + itemPerPage)
})
</script>
3 changes: 3 additions & 0 deletions pages/news/page/[page].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<NewsList />
</template>

0 comments on commit 7823da8

Please sign in to comment.