This repository has been archived by the owner on Aug 3, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
305 additions
and
6,821 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,3 +36,4 @@ next-env.d.ts | |
|
||
.vscode | ||
.vscode/settings.json | ||
pnpm-lock.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { notFound } from "next/navigation"; // Importing the function to show the "not found" page | ||
import { getPostData, getSortedPostsData } from "@/lib/utils/blog/getPosts"; | ||
import { Card } from "@radix-ui/themes"; | ||
import getFormattedDate from "@/lib/utils"; | ||
import "./styles.css"; | ||
|
||
// Function to generate static page parameters | ||
export function generateStaticParams() { | ||
const posts = getSortedPostsData(); // Getting sorted post data | ||
return posts.map((post) => ({ | ||
postId: post.id, // Using the post's ID as a parameter | ||
})); | ||
} | ||
|
||
// Function to generate page metadata | ||
export function generateMetadata({ params }: { params: { postId: string } }) { | ||
const posts = getSortedPostsData(); // Getting sorted post data | ||
const { postId } = params; // Extracting the post ID from parameters | ||
|
||
const post = posts.find((post) => post.id === postId); // Finding the post with the given ID | ||
|
||
if (!post) { | ||
return { | ||
title: "Post Not Found", // Using "Post Not Found" as the title if the post is not found | ||
description: "This post does not exist.", // Add a description for SEO | ||
keywords: [], // Add an empty tags array to avoid errors | ||
author: "Unknown", // Add an unknown author to avoid errors | ||
}; | ||
} | ||
|
||
return { | ||
title: post.title, // Using the post's title as the title | ||
description: post.description, | ||
keywords: post.keywords, // Using the post's tags as the tags | ||
author: post.author, // Using the post's author as the author | ||
}; | ||
} | ||
|
||
// Main function to create the post page | ||
export default async function Post({ params }: { params: { postId: string } }) { | ||
const posts = getSortedPostsData(); // Getting sorted post data | ||
const { postId } = params; // Extracting the post ID from parameters | ||
const page = posts.find((post) => post.id === postId); // Finding the post with the given ID | ||
if (!page) notFound(); // Displaying a 404 error if the post is not found | ||
const { title, date, contentHtml, author, keywords } = | ||
await getPostData(postId); // Fetching post data | ||
|
||
const pubDate = getFormattedDate(date); // Getting a formatted version of the date | ||
|
||
return ( | ||
<div className="mt-10 flex min-h-screen w-full justify-center px-2"> | ||
<Card> | ||
<article> | ||
<h1 className="text-3xl font-bold">{title}</h1> | ||
<p className="font-thin"> | ||
{pubDate} / Author: {author} | ||
</p> | ||
<article | ||
dangerouslySetInnerHTML={{ __html: contentHtml }} | ||
className="article" | ||
/> | ||
</article> | ||
</Card> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* Heading Styles for article */ | ||
.article h1 { | ||
margin-top: 1rem; | ||
font-size: 2.25rem; | ||
font-weight: bold; | ||
} | ||
|
||
.article h2 { | ||
font-size: 1.5rem; | ||
font-weight: bold; | ||
} | ||
|
||
.article h3 { | ||
font-size: 1.25rem; | ||
font-weight: bold; | ||
} | ||
|
||
/* Paragraph Styles for article */ | ||
.article p { | ||
font-size: 1rem; | ||
line-height: 1.6; | ||
} | ||
|
||
/* Emphasis for article */ | ||
.article em { | ||
font-style: italic; | ||
} | ||
|
||
/* Bold Text for article */ | ||
.article strong { | ||
font-weight: bold; | ||
} | ||
|
||
/* Link Styles for article */ | ||
.article a { | ||
text-decoration: none; | ||
} | ||
|
||
/* Visited Links for article */ | ||
.article a:visited { | ||
} | ||
|
||
/* Hovering Over Links for article */ | ||
.article a:hover { | ||
text-decoration: underline; | ||
} | ||
|
||
/* Lists for article */ | ||
.article ul { | ||
list-style-type: disc; | ||
margin-left: 1.5rem; | ||
} | ||
|
||
.article ol { | ||
list-style-type: decimal; | ||
margin-left: 1.5rem; | ||
} | ||
|
||
.article li { | ||
font-size: 1rem; | ||
margin-bottom: 0.5rem; | ||
} | ||
|
||
/* Block Quotes for article */ | ||
.article blockquote { | ||
border-left: 0.25rem solid #333; | ||
margin: 0; | ||
padding: 1rem 2rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,29 @@ | ||
import { getSiteUrl } from "@/lib/utils"; | ||
import { getSortedPostsData } from "@/lib/utils/blog/getPosts"; | ||
import { MetadataRoute } from "next"; | ||
|
||
export default async function sitemap(): Promise<MetadataRoute.Sitemap> { | ||
const posts = getSortedPostsData(); | ||
|
||
return [ | ||
{ | ||
url: "https://www.githubprofileviewer.com/", | ||
lastModified: new Date(), | ||
changeFrequency: "monthly", | ||
priority: 1, | ||
}, | ||
...posts.map((post: BlogPost) => ({ | ||
url: `${getSiteUrl()}/blog/${post.title}`, | ||
lastModified: new Date(), | ||
changeFrequency: "monthly" as | ||
| "monthly" | ||
| "always" | ||
| "hourly" | ||
| "daily" | ||
| "weekly" | ||
| "yearly" | ||
| "never", | ||
priority: 1, | ||
})), | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import fs from "fs"; | ||
import path from "path"; | ||
import matter from "gray-matter"; | ||
import { remark } from "remark"; | ||
import html from "remark-html"; | ||
|
||
// The directory where blog post files are stored. | ||
const postsDirectory = path.join(process.cwd(), "public/posts"); | ||
|
||
// This function retrieves and sorts data from Markdown files representing blog posts. | ||
/** | ||
* Gets all posts data sorted by date in descending order. | ||
* | ||
* Reads the Markdown files from the posts directory, parses the metadata, | ||
* and returns an array of BlogPost objects sorted by date. | ||
*/ | ||
export function getSortedPostsData() { | ||
// Get file names under /posts directory | ||
const fileNames = fs.readdirSync(postsDirectory); | ||
|
||
// Create an array to store all post data | ||
const allPostsData = fileNames.map((fileName) => { | ||
// Remove ".md" extension from the file name to get the post ID | ||
const id = fileName.replace(/\.md$/, ""); | ||
|
||
// Read the content of the Markdown file as a string | ||
const fullPath = path.join(postsDirectory, fileName); | ||
const fileContents = fs.readFileSync(fullPath, "utf8"); | ||
|
||
// Use gray-matter to parse the post's metadata section | ||
const matterResult = matter(fileContents); | ||
|
||
// Create a BlogPost object with extracted data | ||
const blogPost: BlogPost = { | ||
id, | ||
title: matterResult.data.title, | ||
date: matterResult.data.date, | ||
description: matterResult.data.description, | ||
author: matterResult.data.author, | ||
keywords: matterResult.data.keywords, | ||
}; | ||
//console.log(blogPost.date); | ||
// Combine the data with the post ID | ||
return blogPost; | ||
}); | ||
|
||
// Sort the posts by date in descending order | ||
return allPostsData.sort((a, b) => (a.date < b.date ? 1 : -1)); | ||
} | ||
|
||
/** | ||
* Filters the posts from getSortedPostsData() to only | ||
* include posts with a date between the given start and end dates. | ||
* | ||
* @param startDate - The minimum date for posts to include | ||
* @param endDate - The maximum date for posts to include | ||
* @returns The filtered array of posts within the date range | ||
*/ | ||
export const getPostsInDateRange = (startDate: any, endDate: any) => { | ||
console.log("startDate: " + startDate + "\nendDate: " + endDate); | ||
// Get all posts | ||
const allPostsData = getSortedPostsData(); | ||
|
||
// Filter posts that fall within the specified date range | ||
const postsInDateRange = allPostsData.filter((post) => { | ||
const postDate = new Date(post.date); | ||
return postDate >= startDate && postDate <= endDate; | ||
}); | ||
return postsInDateRange; | ||
}; | ||
|
||
// This asynchronous function retrieves and processes data for a specific blog post. | ||
/** | ||
* Retrieves the metadata and content for a blog post by ID, converts the content from Markdown to HTML, | ||
* and returns a BlogPost object enriched with the generated HTML content. | ||
*/ | ||
export async function getPostData(id: string) { | ||
// Construct the full path to the Markdown file for the specified post | ||
const fullPath = path.join(postsDirectory, `${id}.md`); | ||
|
||
// Read the content of the Markdown file as a string | ||
const fileContents = fs.readFileSync(fullPath, "utf8"); | ||
|
||
// Use gray-matter to parse the post's metadata section | ||
const matterResult = matter(fileContents); | ||
|
||
// Process the content using the remark and html plugins to convert Markdown to HTML | ||
const processedContent = await remark() | ||
.use(html) | ||
.process(matterResult.content); | ||
|
||
// Convert the processed content to a string of HTML | ||
const contentHtml = processedContent.toString(); | ||
|
||
// Create a BlogPost object with HTML content | ||
const blogPostWithHTML: BlogPost & { contentHtml: string } = { | ||
id, | ||
title: matterResult.data.title, | ||
date: matterResult.data.date, | ||
description: matterResult.data.description, | ||
author: matterResult.data.author, | ||
contentHtml, | ||
keywords: matterResult.data.keywords, | ||
}; | ||
|
||
// Combine the data with the post's ID and return it | ||
return blogPostWithHTML; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
2dfd1d7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
github-profile-viewer – ./
next-github-profile-viewer.vercel.app
github-profile-viewer-sametcn99.vercel.app
githubprofileviewer.com
www.githubprofileviewer.com
github-profile-viewer-git-master-sametcn99.vercel.app