systems-obscure/src/pages/posts.tsx

132 lines
4 KiB
TypeScript
Raw Normal View History

2025-07-07 17:08:27 +01:00
// @ts-nocheck
import { useMemo, useEffect } from "react"
import MainTemplate from "@/templates/MainTemplate"
import { useParams, useNavigate } from "react-router"
import { convertDate } from "@/utils/convertDate"
import {
2025-07-20 19:15:26 +01:00
Pagination,
PaginationContent,
PaginationItem,
PaginationNext,
PaginationPrevious,
2025-07-07 17:08:27 +01:00
} from "@/components/ui/pagination"
import {
2025-07-20 19:15:26 +01:00
Card,
CardDescription,
CardHeader,
CardTitle,
2025-07-07 17:08:27 +01:00
} from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Link } from "react-router"
import { usePosts } from "@/hooks/usePosts"
const PostsPage = () => {
2025-07-20 19:15:26 +01:00
const { page } = useParams()
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const navigate = useNavigate()
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const { posts } = usePosts()
const postsPerPage = 10
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const currentPage = Number(page) || 1
const totalPages = Math.ceil(posts.length / postsPerPage)
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
useEffect(() => {
if (currentPage < 1 || currentPage > totalPages) {
navigate(`/posts/page/1`, { replace: true })
}
}, [currentPage, totalPages, navigate])
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const currentPosts = useMemo(() => {
const startIndex = (currentPage - 1) * postsPerPage
const endIndex = startIndex + postsPerPage
return posts.slice(startIndex, endIndex)
}, [posts, currentPage, postsPerPage])
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const hasNextPage = currentPage < totalPages
const hasPrevPage = currentPage > 1
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const goToNextPage = () => {
if (hasNextPage) {
navigate(`/posts/page/${currentPage + 1}`)
}
}
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
const goToPrevPage = () => {
if (hasPrevPage) {
navigate(`/posts/page/${currentPage - 1}`)
}
}
2025-07-07 17:08:27 +01:00
2025-07-20 19:15:26 +01:00
return (
<MainTemplate>
<div className="mb-5 ">
<h2 className="scroll-m-20 text-2xl font-semibold lg:text-2xl border-b pb-3">
All posts
</h2>
</div>
<div className="min-h-[calc(100vh-200px)] flex flex-col">
<div className="grid grid-cols-1 md:grid-cols-1 gap-3 flex-grow">
{currentPosts.map((post) => (
<Link
to={`/posts/${post.slug}`}
key={post.slug}
className="block no-underline"
>
<Card
key={post.slug}
className="flex flex-col h-full hover:bg-primary/5 py-4 px-0 rounded-none"
>
<CardHeader>
<CardTitle className="leading-snug font-semibold">
{post.title}
</CardTitle>
<CardDescription className="text-sm text-muted-foreground">
<div className="flex justify-between gap-2">
<span className="text-sm">{convertDate(post.date)}</span>
<div className="hidden md:block">
{post.tags.map((tag, i) => (
<Badge
className="ml-2 cursor-pointer"
key={i}
variant="secondary"
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
navigate(`/tags/${tag}`)
}}
>
{tag}
</Badge>
))}
</div>
</div>
</CardDescription>
</CardHeader>
</Card>
</Link>
))}
</div>
<Pagination className="mt-4">
<PaginationContent>
<PaginationItem>
<PaginationPrevious
className={`select-none ${hasPrevPage ? "cursor-pointer" : "cursor-not-allowed opacity-50"}`}
onClick={goToPrevPage}
/>
</PaginationItem>
<PaginationItem>
<PaginationNext
className={`select-none ${hasNextPage ? "cursor-pointer" : "cursor-not-allowed opacity-50"}`}
onClick={goToNextPage}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
</MainTemplate>
)
2025-07-07 17:08:27 +01:00
}
export { PostsPage }