Files
uldp.edu.vn/app/blog/[slug]/components/NewsDetailsContent.tsx

148 lines
5.2 KiB
TypeScript

import Link from "next/link";
import type { BlogPost } from "@/types/blog";
import { editorjsToHtml, getCmsImageUrl } from "@/utils";
import { toSlug } from "@/utils/slugify";
import CommentsSection from "./CommentsSection";
interface NewsDetailsContentProps {
post: BlogPost;
}
export default function NewsDetailsContent({ post }: NewsDetailsContentProps) {
// Lấy comments từ post (đã được bao gồm trong API response)
const postComments = post.comments || [];
// Lấy base URL cho EditorJS images
const baseUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
// URL tuyệt đối của bài viết để share lên mạng xã hội
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000";
const postUrl = `${siteUrl}/blog/${post.slug}`;
const encodedPostUrl = encodeURIComponent(postUrl);
const encodedTitle = encodeURIComponent(post.title);
// Chuyển đổi EditorJS content sang HTML
const renderContent = () => {
const html = editorjsToHtml(post.content, baseUrl);
return { __html: html };
};
// Chuyển đổi EditorJS contentAfterQuote sang HTML
const renderContentAfterQuote = () => {
const html = editorjsToHtml(post.contentAfterQuote, baseUrl);
return { __html: html };
};
return (
<div className="col-lg-8 col-12">
<div className="news-details-post">
<div className="news-details-image">
<img
src={getCmsImageUrl(post.featuredImage) || "/assets/img/inner-page/news-details/details-1.jpg"}
alt={post.title}
/>
</div>
<div className="details-content">
<ul className="news-list">
<li>
<i className="fa-solid fa-user"></i> By {post.author}
</li>
<li>
<i className="fa-solid fa-calendar-days"></i> {post.publishedAt}
</li>
<li>
<i className="fa-solid fa-comments"></i> {postComments.length} Comments
</li>
</ul>
<h2>{post.title}</h2>
<div className="editorjs-render" dangerouslySetInnerHTML={renderContent()} />
{/* Hình ảnh gallery */}
{post.galleryImages && post.galleryImages.length > 0 && (
<div className="row g-4 gallery-images-row">
{post.galleryImages.map((image, index) => (
<div key={index} className={post.galleryImages!.length === 1 ? "col-12" : "col-lg-6 gallery-item"}>
<div className="thumb">
<img src={getCmsImageUrl(image)} alt={`${post.title} - Image ${index + 1}`} />
</div>
</div>
))}
</div>
)}
{/* Quote/Sidebar */}
{post.quote && (
<div className="sideber mt-4 mb-3">
<h5>{post.quote}</h5>
</div>
)}
{/* Nội dung sau Quote */}
{post.contentAfterQuote && (
<div
className="editorjs-render"
dangerouslySetInnerHTML={renderContentAfterQuote()}
/>
)}
{/* Tags và Social Share */}
<div className="row tag-share-wrap mt-4 mb-5">
<div className="col-lg-8 col-12">
<div className="tagcloud">
<span>Tags:</span>
{post.tags.map((tagName) => {
// Tạo slug từ tên tag (hỗ trợ tiếng Việt)
const tagSlug = toSlug(tagName);
return (
<Link key={tagName} href={`/blog/tag/${tagSlug}`}>
{tagName}
</Link>
);
})}
</div>
</div>
<div className="col-lg-4 col-12 mt-3 mt-lg-0 text-lg-end">
<div className="social-share">
<a
href={`https://twitter.com/intent/tweet?url=${encodedPostUrl}&text=${encodedTitle}`}
target="_blank"
rel="noopener noreferrer"
aria-label="Share on Twitter"
>
<i className="fab fa-twitter"></i>
</a>
<a
href={`https://www.facebook.com/sharer/sharer.php?u=${encodedPostUrl}`}
target="_blank"
rel="noopener noreferrer"
aria-label="Share on Facebook"
>
<i className="fab fa-facebook-f"></i>
</a>
<a
href={`https://www.linkedin.com/sharing/share-offsite/?url=${encodedPostUrl}`}
target="_blank"
rel="noopener noreferrer"
aria-label="Share on LinkedIn"
>
<i className="fab fa-linkedin-in"></i>
</a>
<a
href={postUrl}
target="_blank"
rel="noopener noreferrer"
aria-label="Open blog post"
>
<i className="fa-solid fa-link"></i>
</a>
</div>
</div>
</div>
<CommentsSection slug={post.slug} comments={postComments} />
</div>
</div>
</div>
);
}