// frontend/src/pages/BlogPost.tsx import { useState, useEffect } from "react"; import { useParams, useNavigate } from "react-router-dom"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import rehypeRaw from "rehype-raw"; interface Post { id: number; title: string; content: string; created_at: string; } function BlogPost() { const { id } = useParams<{ id: string }>(); const [post, setPost] = useState(null); const [isLoading, setIsLoading] = useState(true); const navigate = useNavigate(); useEffect(() => { if (id) { fetchPost(id); } }, [id]); const fetchPost = async (postId: string) => { try { const response = await fetch(`/api/v1/posts/${postId}`); if (response.ok) { const data = await response.json(); setPost(data.data || data); } else { navigate("/blog"); } } catch (error) { console.error("Failed to fetch post:", error); navigate("/blog"); } finally { setIsLoading(false); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric", }); }; if (isLoading) { return (
Loading...
); } if (!post) { return (
Post not found
); } return (
{/* Back Button */} {/* Article Header */}

{post.title}

{Math.ceil(post.content.length / 1000)} min reading
{/* Article Content */}
{post.content}
); } export default BlogPost;