refactor: update article service methods to use external ID and improve caching
All checks were successful
Build and Test / run-test (20.x) (push) Successful in 2m5s

This commit is contained in:
2026-04-17 01:43:31 -03:00
parent 93d66315a1
commit e2960027f2
8 changed files with 71 additions and 68 deletions

View File

@@ -1,5 +1,6 @@
import { getArticleBySlug } from '@/lib/feature/article/article.external';
import { ArrowLeftIcon, CalendarIcon, ClockIcon } from 'lucide-react';
import { cacheTag } from 'next/cache';
import Link from 'next/link';
import { notFound } from 'next/navigation';
import { Suspense } from 'react';
@@ -10,10 +11,6 @@ type ArticlePageProps = {
params: Promise<{ slug: string }>;
};
type ArticleContentProps = {
params: Promise<{ slug: string }>;
};
function readingTime(text: string): number {
const words = text.trim().split(/\s+/).length;
return Math.max(1, Math.ceil(words / 200));
@@ -68,8 +65,11 @@ const ArticleContentSkeleton = () => (
</article>
);
const ArticleContent = async ({ params }: ArticleContentProps) => {
const { slug } = await params;
const ArticleContent = async ({ slug }: { slug: string }) => {
'use cache';
cacheTag(`article:slug:${slug}`);
const articleResult = await getArticleBySlug(slug);
if (!articleResult.ok) throw articleResult.error;
const article = articleResult.value;
@@ -144,10 +144,15 @@ const ArticleContent = async ({ params }: ArticleContentProps) => {
);
};
const ArticlePage = ({ params }: ArticlePageProps) => {
const ArticleContentWrapper = async ({ params }: ArticlePageProps) => {
const { slug } = await params;
return <ArticleContent slug={slug} />;
};
const ArticlePage = (props: ArticlePageProps) => {
return (
<Suspense fallback={<ArticleContentSkeleton />}>
<ArticleContent params={params} />
<ArticleContentWrapper {...props} />
</Suspense>
);
};

View File

@@ -1,15 +1,23 @@
import { ArticleList } from '@/ui/components/internal/article/article-list';
import { ArticleListSkeleton } from '@/ui/components/internal/article/article-list-skeleton';
import { Suspense } from 'react';
const DEFAULT_PAGE_SIZE = 4;
type HomeProps = {
searchParams?: { page?: string; pageSize?: string };
searchParams?: Promise<{ page?: string; pageSize?: string }>;
};
const Home = async ({ searchParams }: HomeProps) => {
const page = Number(searchParams?.page) || 0;
const pageSize = Number(searchParams?.pageSize) || DEFAULT_PAGE_SIZE;
const ArticleListWrapper = async ({ searchParams }: HomeProps) => {
const params = await searchParams;
const page = Number(params?.page) || 1;
const pageSize = Number(params?.pageSize) || DEFAULT_PAGE_SIZE;
return <ArticleList page={page} pageSize={pageSize} />;
};
const Home = async (props: HomeProps) => {
return (
<div className='container mx-auto w-full flex-1 px-4 py-12 md:py-16'>
<div className='mb-10 border-b border-border pb-8'>
@@ -20,7 +28,13 @@ const Home = async ({ searchParams }: HomeProps) => {
Latest Articles
</h1>
</div>
<ArticleList page={page} pageSize={pageSize} />
<Suspense
fallback={
<ArticleListSkeleton skeletonSize={DEFAULT_PAGE_SIZE} />
}
>
<ArticleListWrapper {...props} />
</Suspense>
</div>
);
};