CMU Coding Bootcamp
at main 3.0 kB view raw
1import { useParams, Outlet } from "react-router"; 2import { posts } from "../lib/post"; 3import { Link } from "react-router"; 4import { ContentState, convertFromRaw, Editor, EditorState } from "draft-js"; 5import { useState } from "react"; 6import { useNavigate } from "react-router"; 7 8export function BlogPostDetail({ 9 deletePost, 10}: { 11 deletePost: (id: number) => void; 12}) { 13 const { postId } = useParams(); 14 const post = posts.find((post) => post.id === parseInt(postId!)); 15 const [editorState, setEditorState] = useState(() => { 16 try { 17 const data = JSON.parse(`"${post?.content ?? ""}"`); 18 return EditorState.createWithContent(convertFromRaw(data)); 19 } catch { 20 console.log("fallback"); 21 return EditorState.createWithContent( 22 ContentState.createFromText(post?.content ?? ""), 23 ); 24 } 25 }); 26 const navigate = useNavigate(); 27 28 if (!post) { 29 return <div>Post not found</div>; 30 } 31 32 const formattedDate = new Date(post.datePosted).toLocaleDateString("en-US", { 33 month: "long", 34 day: "numeric", 35 year: "numeric", 36 }); 37 38 return ( 39 <> 40 <title>{post.title}</title> 41 <div className="md:grid md:grid-cols-3 flex flex-col w-full"> 42 <Link 43 to="/" 44 className="text-gray-700 dark:text-gray-200 hover:text-gray-400 flex justify-center items-center w-16 mb-4 md:mb-0" 45 > 46 Home 47 </Link> 48 <h1 className="text-3xl md:text-4xl font-bold text-center mb-4 md:mb-0"> 49 {post.title} 50 </h1> 51 <div className="flex md:justify-end items-center"> 52 <Link to={`/post?postId=${post.id}`} className="w-1/3"> 53 <div className="bg-blue-500 hover:bg-blue-700 text-white w-full font-bold py-2 px-4 rounded cursor-pointer text-center"> 54 Edit Post 55 </div> 56 </Link> 57 </div> 58 </div> 59 <div className="flex flex-col gap-1 md:gap-2.5 justify-center items-center mb-1.5 md:mb-2.5"> 60 <p className="text-gray-700 dark:text-gray-400 text-sm md:text-lg"> 61 By: {post.author} 62 </p> 63 <p className="text-gray-600 dark:text-gray-500 text-xs md:text-base"> 64 Published on {formattedDate} 65 </p> 66 </div> 67 <div className="text-sm md:text-lg md:w-3xl w-full md:mb-10"> 68 <Editor 69 editorState={editorState} 70 onChange={setEditorState} 71 readOnly={true} 72 /> 73 </div> 74 <button 75 className="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded cursor-pointer w-full md:w-3xl" 76 onClick={() => { 77 if (window.confirm("Are you sure you want to delete this post?")) { 78 deletePost(post.id); 79 navigate("/"); 80 } 81 }} 82 > 83 Delete 84 </button> 85 </> 86 ); 87} 88 89export function PostLayout() { 90 return ( 91 <div className="flex flex-col justify-center gap-3.5 md:gap-5 items-center p-5 w-screen"> 92 <Outlet /> 93 </div> 94 ); 95}