Files
iiEasy/components/NewsArticleDetail.tsx

148 lines
6.2 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import { CurrentView, NewsArticle } from '../types';
import { SECTION_IDS, NEWS_ARTICLE_DETAIL_CONTENT } from '../constants'; // Removed mockNews
import Button from './Button';
import { ArrowUturnLeftIcon, ChevronRightIcon } from './icons';
import ItemDetailNavigation from './ItemDetailNavigation';
import NewsCard from './NewsCard';
import GalleryComponent from './GalleryComponent'; // Import GalleryComponent
interface NewsArticleDetailProps {
itemId: string;
allNews: NewsArticle[];
setCurrentView: (view: CurrentView) => void;
setSelectedItemId: (id: string | null) => void;
}
const NewsArticleDetail: React.FC<NewsArticleDetailProps> = ({ itemId, allNews, setCurrentView, setSelectedItemId }) => {
const article = allNews.find(p => p.id === itemId);
const handleBackClick = () => {
setCurrentView('newsAll');
setSelectedItemId(null);
};
const handleNavigateItem = (newItemId: string) => {
setSelectedItemId(newItemId);
};
const handleShowAllKeepReading = (e: React.MouseEvent<HTMLAnchorElement>) => {
e.preventDefault();
setCurrentView('newsAll');
setSelectedItemId(null);
};
if (!article) {
return (
<section id={SECTION_IDS.newsArticleDetailPage} className="py-16 md:py-24 min-h-screen flex items-center justify-center">
<div className="container mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-2xl font-semibold text-slate-700">{NEWS_ARTICLE_DETAIL_CONTENT.notFoundTitle}</h1>
<Button onClick={handleBackClick} leftIcon={<ArrowUturnLeftIcon />} className="mt-8">
{NEWS_ARTICLE_DETAIL_CONTENT.backButtonText}
</Button>
</div>
</section>
);
}
const currentIndex = allNews.findIndex(p => p.id === itemId);
const previousArticle = currentIndex > 0 ? allNews[currentIndex - 1] : undefined;
const nextArticle = currentIndex < allNews.length - 1 ? allNews[currentIndex + 1] : undefined;
const relatedArticles = allNews
.filter(p => p.id !== itemId)
.slice(0, 3);
return (
<section
id={SECTION_IDS.newsArticleDetailPage}
className="py-16 md:py-24 bg-white min-h-screen"
>
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<Button
variant="outline"
size="sm"
onClick={handleBackClick}
leftIcon={<ArrowUturnLeftIcon />}
className="mb-6"
>
{NEWS_ARTICLE_DETAIL_CONTENT.backButtonText}
</Button>
{article.imageUrl && (
<div className="mb-8 rounded-lg overflow-hidden">
<img src={article.imageUrl} alt={article.title} className="w-full h-auto object-cover max-h-[50vh]" />
</div>
)}
<div className="max-w-3xl mx-auto">
<header className="mb-8 md:mb-12">
<h1 className="font-quicksand text-3xl sm:text-4xl md:text-5xl font-bold text-slate-800 mb-3">
{article.title}
</h1>
<div className="font-inter text-sm text-slate-500">
<span className="font-semibold text-slate-600">{article.category}</span>
<span className="mx-1.5"></span>
<span>{article.date}</span>
</div>
</header>
<article className="prose prose-lg max-w-none font-inter text-slate-700">
{article.description && <p className="lead text-xl">{article.description}</p>}
{typeof article.fullContent === 'string' ? (
<div dangerouslySetInnerHTML={{ __html: article.fullContent }} />
) : (
article.fullContent
)}
</article>
{article.gallery && article.gallery.length > 0 && (
<GalleryComponent items={article.gallery} title={NEWS_ARTICLE_DETAIL_CONTENT.galleryTitle} />
)}
<ItemDetailNavigation
previousItem={previousArticle ? { id: previousArticle.id, title: previousArticle.title } : undefined}
nextItem={nextArticle ? { id: nextArticle.id, title: nextArticle.title } : undefined}
onNavigate={handleNavigateItem}
previousItemButtonLabel={NEWS_ARTICLE_DETAIL_CONTENT.previousItemButtonLabel || `Предыдущая ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypeSingular}`}
nextItemButtonLabel={NEWS_ARTICLE_DETAIL_CONTENT.nextItemButtonLabel || `Следующая ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypeSingular}`}
noPreviousItemText={NEWS_ARTICLE_DETAIL_CONTENT.noPreviousItemText || `Это первая ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypeSingular}`}
noNextItemText={NEWS_ARTICLE_DETAIL_CONTENT.noNextItemText || `Это последняя ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypeSingular}`}
themeColorClass="slate"
/>
</div>
{relatedArticles.length > 0 && (
<div className="mt-12 md:mt-16">
<div className="flex justify-between items-baseline mb-8">
<h2 className="font-quicksand text-3xl font-bold text-slate-800">
{NEWS_ARTICLE_DETAIL_CONTENT.keepReadingTitle || "Другие новости"}
</h2>
<a
href={`#${SECTION_IDS.newsAllPage}`}
onClick={handleShowAllKeepReading}
className="group inline-flex items-center text-base font-medium text-slate-700 hover:text-black transition-colors whitespace-nowrap"
aria-label={`Посмотреть все ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypePlural}`}
>
{NEWS_ARTICLE_DETAIL_CONTENT.viewAllButtonText || `Все ${NEWS_ARTICLE_DETAIL_CONTENT.itemTypePlural}`}
<ChevronRightIcon className="ml-1 w-5 h-5 transform group-hover:translate-x-1 transition-transform duration-200" />
</a>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 lg:gap-8">
{relatedArticles.map(relatedArticle => (
<NewsCard
key={relatedArticle.id}
article={relatedArticle}
setCurrentView={setCurrentView}
setSelectedItemId={setSelectedItemId}
/>
))}
</div>
</div>
)}
</div>
</section>
);
};
export default NewsArticleDetail;