Skip to content

Commit 9d965b6

Browse files
committed
shown posts
1 parent 7b4e97a commit 9d965b6

File tree

6 files changed

+114
-23
lines changed

6 files changed

+114
-23
lines changed

public/data/shownPosts.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[
2+
{
3+
"file": "code-example-post",
4+
"date": "2025-10-15",
5+
"updated": "2025-10-15"
6+
},
7+
8+
{
9+
"file": "first-post",
10+
"date": "2025-10-14",
11+
"updated": "2025-10-15"
12+
},
13+
14+
{
15+
"file": "long-post",
16+
"date": "2025-10-13",
17+
"updated": "2025-10-14"
18+
},
19+
20+
{
21+
"file": "second-post",
22+
"date": "2025-10-12",
23+
"updated": "2025-10-13"
24+
}
25+
]

src/components/PostItem.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
11
import React from 'react';
22
import { Link } from 'react-router-dom';
33

4-
const PostItem = ({ slug }) => {
4+
const PostItem = ({ slug, date, updatedDate }) => {
55
const title = slug.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
6-
const date = 'October 15, 2025'; // Placeholder date
6+
7+
// Format the date from YYYY-MM-DD to 'Month Day, Year'
8+
const formattedDate = new Date(date).toLocaleDateString('en-US', {
9+
year: 'numeric',
10+
month: 'long',
11+
day: 'numeric',
12+
});
13+
14+
// Format the updated date if it exists
15+
const formattedUpdatedDate = updatedDate ? new Date(updatedDate).toLocaleDateString('en-US', {
16+
year: 'numeric',
17+
month: 'long',
18+
day: 'numeric',
19+
}) : null;
720

821
return (
922
<Link to={`/blog/${slug}`} className="block p-8 my-4 border border-gray-700/50 rounded-lg shadow-lg cursor-pointer hover:bg-gray-800/30 transition-colors">
1023
<article>
1124
<div className="flex items-center">
12-
<p className="text-sm text-gray-400">{date}</p>
25+
<p className="text-sm text-gray-400">{formattedDate}</p>
1326
<div className="ml-4 flex-grow flex items-center">
1427
<h2 className="text-xl font-semibold text-white hover:text-primary-400 transition-colors">
1528
{title}
1629
</h2>
1730
</div>
31+
{formattedUpdatedDate && updatedDate !== date && (
32+
<span className="ml-4 px-2 py-1 text-xs font-medium text-blue-400 bg-blue-400/10 rounded-full">Updated: {formattedUpdatedDate}</span>
33+
)}
1834
<span className="ml-4 flex-shrink-0 text-sm font-medium text-primary-400 hover:text-primary-500 transition-colors">
1935
Read post &rarr;
2036
</span>

src/components/PostMetadata.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import React from 'react';
22
import Label from './Label';
33

4-
const PostMetadata = ({ metadata, readingProgress, isAtTop }) => {
4+
const PostMetadata = ({ metadata, readingProgress, isAtTop, overrideDate, updatedDate }) => {
55
if (!metadata) {
66
return null;
77
}
88

9-
const postDate = new Date(metadata.date);
10-
const formattedDate = isNaN(postDate) ? 'Invalid Date' : postDate.toLocaleDateString();
9+
const displayDate = overrideDate || (metadata.date ? new Date(metadata.date).toLocaleDateString() : 'Invalid Date');
1110

1211
const handleButtonClick = () => {
1312
if (isAtTop) {
@@ -28,8 +27,14 @@ const PostMetadata = ({ metadata, readingProgress, isAtTop }) => {
2827
</div>
2928
<div>
3029
<Label>Date</Label>
31-
<p className="text-gray-300">{formattedDate}</p>
30+
<p className="text-gray-300">{displayDate}</p>
3231
</div>
32+
{updatedDate && (
33+
<div>
34+
<Label>Updated</Label>
35+
<p className="text-gray-300">{updatedDate}</p>
36+
</div>
37+
)}
3338
{metadata.tags && (
3439
<div>
3540
<Label>Tags</Label>
@@ -60,6 +65,6 @@ const PostMetadata = ({ metadata, readingProgress, isAtTop }) => {
6065
</div>
6166
</aside>
6267
);
63-
};
68+
}
6469

6570
export default PostMetadata;

src/pages/BlogPage.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,23 @@ const BlogPage = () => {
77
const [posts, setPosts] = useState([]);
88

99
useEffect(() => {
10-
// In a real app, you'd fetch this from a CMS or API
11-
const postSlugs = ['long-post', 'first-post', 'second-post', 'code-example-post'];
12-
setPosts(postSlugs);
10+
const fetchPostSlugs = async () => {
11+
try {
12+
const response = await fetch('/data/shownPosts.json');
13+
if (response.ok) {
14+
const slugs = await response.json();
15+
setPosts(slugs);
16+
} else {
17+
console.error('Failed to fetch post slugs');
18+
setPosts([]);
19+
}
20+
} catch (error) {
21+
console.error('Error fetching post slugs:', error);
22+
setPosts([]);
23+
}
24+
};
25+
26+
fetchPostSlugs();
1327
}, []);
1428

1529
return (
@@ -28,8 +42,8 @@ const BlogPage = () => {
2842
</div>
2943
<div className="mt-16">
3044
<div className="">
31-
{posts.map(slug => (
32-
<PostItem key={slug} slug={slug} />
45+
{posts.map(post => (
46+
<PostItem key={post.file} slug={post.file} date={post.date} updatedDate={post.updated} />
3347
))}
3448
</div>
3549
</div>

src/pages/BlogPostPage.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const LinkRenderer = ({ href, children }) => {
1717
const BlogPostPage = () => {
1818
const { slug } = useParams();
1919
const [post, setPost] = useState(null);
20+
const [shownPostsData, setShownPostsData] = useState([]);
2021
const [loading, setLoading] = useState(true);
2122
const [readingProgress, setReadingProgress] = useState(0);
2223
const [isAtTop, setIsAtTop] = useState(true); // New state for tracking if at top
@@ -26,16 +27,28 @@ const BlogPostPage = () => {
2627
const fetchPost = async () => {
2728
setLoading(true);
2829
try {
29-
const response = await fetch(`/posts/${slug}.md`);
30-
if (response.ok) {
31-
const text = await response.text();
30+
const [postResponse, shownPostsResponse] = await Promise.all([
31+
fetch(`/posts/${slug}.md`),
32+
fetch('/data/shownPosts.json')
33+
]);
34+
35+
if (postResponse.ok) {
36+
const text = await postResponse.text();
3237
const content = fm(text);
3338
setPost(content);
3439
} else {
3540
setPost({ attributes: { title: 'Post not found' }, body: '' });
3641
}
42+
43+
if (shownPostsResponse.ok) {
44+
const data = await shownPostsResponse.json();
45+
setShownPostsData(data);
46+
} else {
47+
console.error('Failed to fetch shownPosts.json');
48+
}
49+
3750
} catch (error) {
38-
console.error('Error fetching post:', error);
51+
console.error('Error fetching post or shownPosts.json:', error);
3952
setPost({ attributes: { title: 'Error loading post' }, body: '' });
4053
}
4154
setLoading(false);
@@ -67,6 +80,10 @@ const BlogPostPage = () => {
6780
return <div className="text-center py-16">Post not found</div>;
6881
}
6982

83+
const currentPostData = shownPostsData.find(item => item.file === slug);
84+
const postDate = currentPostData ? currentPostData.date : null;
85+
const updatedDate = currentPostData ? currentPostData.updated : null;
86+
7087
return (
7188
<div className="bg-gray-900 py-16 sm:py-24">
7289
<div className="mx-auto max-w-7xl px-6 lg:px-8">
@@ -80,7 +97,7 @@ const BlogPostPage = () => {
8097
</div>
8198
</div>
8299
<div className="hidden lg:block">
83-
<PostMetadata metadata={post.attributes} readingProgress={readingProgress} isAtTop={isAtTop} />
100+
<PostMetadata metadata={post.attributes} readingProgress={readingProgress} isAtTop={isAtTop} overrideDate={postDate} updatedDate={updatedDate} />
84101
</div>
85102
</div>
86103
</div>

src/pages/HomePage.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,23 @@ const HomePage = () => {
1111
const pinnedProjects = projects.filter(p => p.pinned);
1212

1313
useEffect(() => {
14-
// In a real app, you'd fetch this from a CMS or API
15-
const postSlugs = ['long-post', 'first-post', 'second-post'];
16-
setPosts(postSlugs);
14+
const fetchPostSlugs = async () => {
15+
try {
16+
const response = await fetch('/data/shownPosts.json');
17+
if (response.ok) {
18+
const postsData = await response.json();
19+
setPosts(postsData);
20+
} else {
21+
console.error('Failed to fetch post slugs');
22+
setPosts([]);
23+
}
24+
} catch (error) {
25+
console.error('Error fetching post slugs:', error);
26+
setPosts([]);
27+
}
28+
};
29+
30+
fetchPostSlugs();
1731
}, []);
1832

1933
if (loading) {
@@ -57,8 +71,8 @@ const HomePage = () => {
5771
<FaBlog className="text-primary-400" /> Recent Blog Posts
5872
</h2>
5973
<div className="mt-8">
60-
{posts.slice(0, 5).map(slug => (
61-
<PostItem key={slug} slug={slug} />
74+
{posts.slice(0, 5).map(post => (
75+
<PostItem key={post.file} slug={post.file} date={post.date} updatedDate={post.updated} />
6276
))}
6377
</div>
6478
<div className="mt-8 text-center">

0 commit comments

Comments
 (0)