testing with adding blog to portfolio website
This commit is contained in:
		
							
								
								
									
										17
									
								
								frontend/src/components/BlogCard.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/src/components/BlogCard.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { Link } from "react-router-dom"; | ||||
|  | ||||
| export const BlogCard = ({ title, description, slug, date }) => { | ||||
|   return ( | ||||
|     <Link to={`/blog/${slug}`} className="no-underline"> | ||||
|       <div className="rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-lg transition-shadow duration-200"> | ||||
|         <div className="space-y-2"> | ||||
|           <h3 className="text-2xl font-semibold tracking-tight">{title}</h3> | ||||
|           <div> | ||||
|             <p className="text-sm text-gray-500">{date}</p> | ||||
|             <p className="mt-2 text-gray-600">{description}</p> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </Link> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										17
									
								
								frontend/src/components/BlogList.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/src/components/BlogList.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { BlogCard } from "./BlogCard"; | ||||
|  | ||||
| export const BlogList = ({ posts }) => { | ||||
|   return ( | ||||
|     <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4"> | ||||
|       {posts.map((post) => ( | ||||
|         <BlogCard | ||||
|           key={post.slug} | ||||
|           title={post.title} | ||||
|           description={post.description} | ||||
|           slug={post.slug} | ||||
|           date={post.date} | ||||
|         /> | ||||
|       ))} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										45
									
								
								frontend/src/components/BlogPost.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								frontend/src/components/BlogPost.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| import { useEffect, useState } from "react"; | ||||
| import { useParams } from "react-router-dom"; | ||||
| import ReactMarkdown from "react-markdown"; | ||||
|  | ||||
| export const BlogPost = () => { | ||||
|   const { slug } = useParams(); | ||||
|   const [content, setContent] = useState(""); | ||||
|   const [metadata, setMetadata] = useState(null); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const fetchPost = async () => { | ||||
|       try { | ||||
|         const post = await import(`../assets/blogs/${slug}.md`); | ||||
|         const response = await fetch(post.default); | ||||
|         const text = await response.text(); | ||||
|         setContent(text); | ||||
|          | ||||
|         // const meta = await import(`../content/metadata/${slug}.json`); | ||||
|         // setMetadata(meta.default); | ||||
|       } catch (error) { | ||||
|         console.error("Error loading blog post:", error); | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     fetchPost(); | ||||
|   }, [slug]); | ||||
|  | ||||
|   if (!content) { | ||||
|     return ( | ||||
|       <div className="flex justify-center items-center min-h-screen"> | ||||
|         <p className="text-gray-600">Loading...</p> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <article className="max-w-3xl mx-auto p-6"> | ||||
|       {/* <h1 className="text-4xl font-bold mb-4">{metadata.title}</h1> | ||||
|       <div className="text-gray-500 mb-8">{metadata.date}</div> */} | ||||
|       <div className="prose prose-lg"> | ||||
|         <ReactMarkdown>{content}</ReactMarkdown> | ||||
|       </div> | ||||
|     </article> | ||||
|   ); | ||||
| }; | ||||
| @ -36,7 +36,7 @@ const Navbar: React.FC<NavProps> = ({toggleDarkMode, darkMode}) => { | ||||
|   return ( | ||||
|     <div className="w-full flex justify-center"> | ||||
|       <nav className="py-5 mb-6 flex justify-between dark:text-white w-full max-w-5xl px-4"> | ||||
|           <button  | ||||
|           <button | ||||
|             onClick={handleCopyEmail} | ||||
|             className="flex items-center space-x-2 hover:bg-gray-100 dark:hover:bg-gray-800 px-3 py-2 rounded-lg transition-colors duration-200 group relative" | ||||
|           > | ||||
| @ -51,7 +51,7 @@ const Navbar: React.FC<NavProps> = ({toggleDarkMode, darkMode}) => { | ||||
|               {copied ? 'Copied!' : 'Click to copy'} | ||||
|             </span> | ||||
|           </button> | ||||
|            | ||||
|  | ||||
|           <ul className="flex items-center"> | ||||
|               <li className="transition ease-in-out delay-50 duration-100 cursor-pointer" | ||||
|               onClick={toggleDarkMode}> | ||||
| @ -64,9 +64,9 @@ const Navbar: React.FC<NavProps> = ({toggleDarkMode, darkMode}) => { | ||||
|               </li> | ||||
|               <li className="transition ease-in-out delay-50 duration-100"> | ||||
|                   <div className="group relative"> | ||||
|                   <a className="text-white p-2 ml-8 inline-flex"  | ||||
|                   href="https://www.linkedin.com/in/taqi-tahmid/details/featured/1735981754176/single-media-viewer/?profileId=ACoAACDU_GsBCgKtvw2bmzbVwTy2WixBG6-e3JM"  | ||||
|                   target="_blank"  | ||||
|                   <a className="text-white p-2 ml-8 inline-flex" | ||||
|                   href="https://www.linkedin.com/in/taqi-tahmid/details/featured/1735981754176/single-media-viewer/?profileId=ACoAACDU_GsBCgKtvw2bmzbVwTy2WixBG6-e3JM" | ||||
|                   target="_blank" | ||||
|                   rel="noreferrer"> | ||||
|                     <FileText className="hover:scale-110 text-gray-800 dark:text-white" size={30} /> | ||||
|                   </a> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user