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

119 lines
4.0 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) {
// Get comments from post (already included in API response)
const postComments = post.comments || [];
// Get base URL for EditorJS images
const baseUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001";
// Convert EditorJS content to HTML
const renderContent = () => {
const html = editorjsToHtml(post.content, baseUrl);
return { __html: html };
};
// Convert EditorJS contentAfterQuote to 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 dangerouslySetInnerHTML={renderContent()} />
{/* Gallery Images */}
{post.galleryImages && post.galleryImages.length > 0 && (
<div className="row g-4 mt-4">
{post.galleryImages.map((image, index) => (
<div key={index} className={post.galleryImages!.length === 1 ? "col-12" : "col-lg-6"}>
<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>
)}
{/* Content After Quote */}
{post.contentAfterQuote && (
<div dangerouslySetInnerHTML={renderContentAfterQuote()} />
)}
{/* Tags and 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) => {
// Generate slug from tag name (Vietnamese-friendly)
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="#" aria-label="Share on Twitter">
<i className="fab fa-twitter"></i>
</a>
<a href="#" aria-label="Share on YouTube">
<i className="fa-brands fa-youtube"></i>
</a>
<a href="#" aria-label="Share on LinkedIn">
<i className="fab fa-linkedin-in"></i>
</a>
<a href="#" aria-label="Share on Facebook">
<i className="fab fa-facebook-f"></i>
</a>
</div>
</div>
</div>
<CommentsSection slug={post.slug} comments={postComments} />
</div>
</div>
</div>
);
}