feature/adds-admin-add-article #1

Merged
HideyoshiNakazone merged 21 commits from feature/adds-admin-add-article into main 2026-04-11 04:30:42 +00:00
Showing only changes of commit 34a662fb30 - Show all commits

View File

@@ -2,6 +2,7 @@ import { getArticleBySlug } from '@/lib/feature/article/article.external';
import { ArrowLeftIcon, CalendarIcon, ClockIcon } from 'lucide-react'; import { ArrowLeftIcon, CalendarIcon, ClockIcon } from 'lucide-react';
import Link from 'next/link'; import Link from 'next/link';
import { notFound } from 'next/navigation'; import { notFound } from 'next/navigation';
import { Suspense } from 'react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
@@ -22,8 +23,48 @@ function formatDate(date: Date): string {
}).format(date); }).format(date);
} }
const ArticlePage = async ({ params }: ArticlePageProps) => { const ArticleContentSkeleton = () => (
const { slug } = await params; <article className='w-full'>
<div className='h-64 w-full animate-pulse bg-muted md:h-96' />
<div className='container mx-auto max-w-3xl px-4'>
<div className='-mt-16 relative z-10'>
<div className='mb-6 h-4 w-24 animate-pulse rounded bg-muted' />
<header className='mb-10'>
<div className='mb-4 space-y-2'>
<div className='h-8 w-full animate-pulse rounded bg-muted' />
<div className='h-8 w-3/4 animate-pulse rounded bg-muted' />
</div>
<div className='mb-5 space-y-2'>
<div className='h-5 w-full animate-pulse rounded bg-muted' />
<div className='h-5 w-2/3 animate-pulse rounded bg-muted' />
</div>
<div className='flex gap-4'>
<div className='h-3 w-28 animate-pulse rounded bg-muted' />
<div className='h-3 w-16 animate-pulse rounded bg-muted' />
</div>
</header>
<hr className='mb-10 border-border' />
<div className='space-y-3 pb-16'>
{[...Array(4)].map((_, i) => (
<div key={i} className='space-y-2'>
<div className='h-4 w-full animate-pulse rounded bg-muted' />
<div className='h-4 w-full animate-pulse rounded bg-muted' />
<div className='h-4 w-5/6 animate-pulse rounded bg-muted' />
</div>
))}
</div>
</div>
</div>
</article>
);
const ArticleContent = async ({ slug }: { slug: string }) => {
const article = await getArticleBySlug(slug); const article = await getArticleBySlug(slug);
if (!article) notFound(); if (!article) notFound();
@@ -96,4 +137,14 @@ const ArticlePage = async ({ params }: ArticlePageProps) => {
); );
}; };
const ArticlePage = async ({ params }: ArticlePageProps) => {
const { slug } = await params;
return (
<Suspense fallback={<ArticleContentSkeleton />}>
<ArticleContent slug={slug} />
</Suspense>
);
};
export default ArticlePage; export default ArticlePage;