115 lines
3.6 KiB
TypeScript
115 lines
3.6 KiB
TypeScript
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
import { faArrowsRotate, faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
|
|
import { Button } from '@/components/ui/button';
|
|
import Image from 'next/image';
|
|
import Link from 'next/link';
|
|
import { notFound } from 'next/navigation';
|
|
import { PageTransition } from '@/components/page-transition';
|
|
|
|
interface WikipediaSummary {
|
|
title: string;
|
|
extract: string;
|
|
thumbnail?: {
|
|
source: string;
|
|
};
|
|
originalimage?: {
|
|
source: string;
|
|
};
|
|
content_urls?: {
|
|
desktop?: {
|
|
page: string;
|
|
};
|
|
};
|
|
}
|
|
|
|
async function getArticleSummary(title: string): Promise<WikipediaSummary | null> {
|
|
try {
|
|
// Wikipedia API expects underscores instead of %20 for spaces
|
|
const apiTitle = title.replace(/%20/g, '_');
|
|
|
|
const response = await fetch(
|
|
`https://en.wikipedia.org/api/rest_v1/page/summary/${apiTitle}`,
|
|
{
|
|
headers: {
|
|
'User-Agent': 'WikiPlus/1.0',
|
|
},
|
|
cache: 'no-store',
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
|
|
return await response.json();
|
|
} catch (error) {
|
|
console.error('Error fetching article summary:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export default async function SummaryPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ title: string }>;
|
|
}) {
|
|
const { title } = await params;
|
|
const article = await getArticleSummary(title);
|
|
|
|
if (!article) {
|
|
notFound();
|
|
}
|
|
|
|
const imageUrl = article.thumbnail?.source || article.originalimage?.source;
|
|
const pageUrl = article.content_urls?.desktop?.page;
|
|
|
|
return (
|
|
<main className="min-h-screen py-10 sm:py-16 px-4 sm:px-6 overflow-hidden">
|
|
<div className="max-w-2xl mx-auto">
|
|
<header className="mb-8 sm:mb-12 animate-[slideInFromTop_0.6s_ease-out]">
|
|
<Link href="/" className="text-gray-500 hover:text-gray-300 text-sm uppercase tracking-widest mb-4 inline-block transition-colors">
|
|
Wiki<span className="text-blue-500">+</span>
|
|
</Link>
|
|
<h1 className="text-3xl sm:text-4xl md:text-5xl font-light text-gray-100 tracking-tight">
|
|
{article.title}
|
|
</h1>
|
|
</header>
|
|
|
|
{imageUrl && (
|
|
<div className="relative w-full aspect-video mb-8 sm:mb-10 rounded-lg overflow-hidden bg-gray-800/50 animate-[fadeInScale_0.8s_ease-out_0.2s_both]">
|
|
<Image
|
|
src={imageUrl}
|
|
alt={article.title}
|
|
fill
|
|
className="object-contain"
|
|
priority
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
<article className="mb-8 sm:mb-12 animate-[slideInFromBottom_0.6s_ease-out_0.4s_both]">
|
|
<p className="text-gray-300 text-lg sm:text-xl leading-relaxed font-light">
|
|
{article.extract}
|
|
</p>
|
|
</article>
|
|
|
|
<footer className="flex flex-col-reverse sm:flex-row items-center justify-between gap-4 pt-6 sm:pt-8 border-t border-gray-800 animate-[slideInFromBottom_0.6s_ease-out_0.6s_both]">
|
|
<Link
|
|
href={`/article/${encodeURIComponent(article.title)}`}
|
|
className="text-gray-500 hover:text-gray-300 text-sm inline-flex items-center gap-2 transition-colors"
|
|
>
|
|
Full article
|
|
<FontAwesomeIcon icon={faArrowUpRightFromSquare} className="text-xs" />
|
|
</Link>
|
|
<PageTransition href="/random">
|
|
<Button variant="outline" className="gap-2 hover:scale-105 active:scale-95 transition-transform w-full sm:w-auto">
|
|
<FontAwesomeIcon icon={faArrowsRotate} />
|
|
New Article
|
|
</Button>
|
|
</PageTransition>
|
|
</footer>
|
|
</div>
|
|
</main>
|
|
);
|
|
}
|